O @GhostInTheSecureShell tem a missão de instalá-lo, pelo menos no Debian, mas definitivamente um recurso incrível. Acho que eventualmente todas essas "duas perguntas CURRENT_TIMESTAMP" serão atenuadas!
21413 Marc Marcio
agora é a função () ou você pode fazer as configurações padrão no nível da coluna.
Anshul Sharma
Respostas:
862
EDIÇÃO IMPORTANTE:
Agora é possível conseguir isso com os campos DATETIME desde o MySQL 5.6.5 , dê uma olhada no outro post abaixo ...
As versões anteriores não podem fazer isso com DATETIME ...
Mas você pode fazer isso com o TIMESTAMP:
mysql>createtable test (str varchar(32), ts TIMESTAMP DEFAULTCURRENT_TIMESTAMP);
Query OK,0rows affected (0.00 sec)
mysql>desc test;+-------+-------------+------+-----+-------------------+-------+| Field | Type |Null|Key|Default| Extra |+-------+-------------+------+-----+-------------------+-------+| str | varchar(32)| YES ||NULL||| ts | timestamp | NO ||CURRENT_TIMESTAMP||+-------+-------------+------+-----+-------------------+-------+2rowsinset(0.00 sec)
mysql>insertinto test (str)values("demo");
Query OK,1row affected (0.00 sec)
mysql>select*from test;+------+---------------------+| str | ts |+------+---------------------+| demo |2008-10-0322:59:52|+------+---------------------+1rowinset(0.00 sec)
mysql>
** CAVEAT: se você definir uma coluna com CURRENT_TIMESTAMP ON como padrão, precisará SEMPRE especificar um valor para essa coluna ou o valor será redefinido automaticamente para "now ()" na atualização. Isso significa que, se você não deseja que o valor seja alterado, sua instrução UPDATE deve conter "[nome da sua coluna] = [nome da sua coluna]" (ou algum outro valor) ou o valor se tornará "agora ()". Estranho, mas é verdade. Eu espero que isso ajude. Estou usando o 5.5.56-MariaDB **
é importante observar que a data e hora tem um intervalo de 1000 a 9999, mas o intervalo para o registro de data e hora é apenas de 1970 a 2038 . isso pode ser um problema se o seu sistema precisar armazenar datas de nascimento ou se você precisar lidar com algo como o plano de pagamento de uma hipoteca de 30 anos. dev.mysql.com/doc/refman/5.0/en/datetime.html
Kip
13
Tenha cuidado também com timestamp como ele atualizações automáticas magicamente ... ver próxima resposta stackoverflow.com/a/1483959/233906
Cerber
6
Ele é possível a partir da versão 5.6.5, ver a resposta de Gustav abaixo (eu percebo a sua resposta foi publicado quando o MySQL ainda era 5.0!)
e2-e4
4
@ Kip, Oi, é possível ter um valor padrão para uma DATEcoluna? (não uma datetimecoluna).
Sajib Acharya 03/03
ti não parece ser possível para colunas DATA: você tem que usar DATETIME tipo de dados
Fabio Napodano
599
Na versão 5.6.5, é possível definir um valor padrão em uma coluna de data e hora e até criar uma coluna que será atualizada quando a linha for atualizada. A definição de tipo:
@FernandoTrindade Você precisa do MySQL versão 5.6.5 ou posterior. Você pode vê-lo trabalhando aqui: sqlfiddle.com/#!9/dd2be
Gustav Bertram
1
@GustavBertram, estou usando a versão 5.6.22, mas ainda assim recebi o erro da seguinte forma: CREATE TABLE tbl (InsertDate DATETIME NÃO NULL PADRÃO CURRENT_TIMESTAMP, UpdateDate TIMESTAMP NULL ON UPDATE CURRENT_TIMESTAMP (6)); Código de erro: 1294. Cláusula ON UPDATE inválida para a coluna 'UpdateDate'
Manish Sapkal
@ManishSapkal Você está usando um TIMESTAMP, não um DATETIME. Além disso, não torne NULL.
O MySQL ( antes da versão 5.6.5 ) não permite que funções sejam usadas para os valores padrão de DateTime. O TIMESTAMP não é adequado devido ao seu comportamento estranho e não é recomendado para uso como dados de entrada. (Veja Padrões de tipo de dados MySQL .)
Eu tenho uma tabela com um campo DateCreated do tipo DateTime. Eu criei um gatilho nessa tabela "Antes de inserir" e " SET NEW.DateCreated=NOW()" e funciona muito bem.
CREATE TRIGGER trigger_foo_SetCreatedAt ANTES DE INSERIR NO FOO PARA CADA LINHA SET NEW.created_at = UTC_TIMESTAMP ();
kgriffs
5
Provavelmente, é melhor usar um carimbo de data e hora do que um gatilho para sanidade futura (manutenção). Este é um caso de uso trivial demais para um acionador, embora seja uma solução.
getWeberForStackExchange 7/11
8
Você provavelmente vai querer valor padrão aparelho sóIF NEW.created_at IS NOT NULL
Petr Peller
132
Para mim, a abordagem do gatilho funcionou melhor, mas eu encontrei um problema com a abordagem. Considere o gatilho básico para definir um campo de data para a hora atual na inserção:
CREATETRIGGER myTable_OnInsert BEFORE INSERTON`tblMyTable`FOR EACH ROWSET NEW.dateAdded = NOW();
Isso geralmente é ótimo, mas digamos que você queira definir o campo manualmente via instrução INSERT, da seguinte forma:
O que acontece é que o gatilho substitui imediatamente o valor fornecido para o campo e, portanto, a única maneira de definir um horário não atual é uma instrução UPDATE de acompanhamento - eca! Para substituir esse comportamento quando um valor é fornecido, tente esse gatilho ligeiramente modificado com o operador IFNULL:
CREATETRIGGER myTable_OnInsert BEFORE INSERTON`tblMyTable`FOR EACH ROWSET NEW.dateAdded = IFNULL(NEW.dateAdded, NOW());
Isso fornece o melhor dos dois mundos: você pode fornecer um valor para a coluna da data e ela será demorada; caso contrário, será padronizada para a hora atual. Ainda é um gueto relativo a algo limpo como DEFAULT GETDATE () na definição da tabela, mas estamos chegando mais perto!
+1 por reconhecer a ressalva com a substituição de valores explícitos do usuário na inserção.
27411 Kip
2
Pessoalmente, acho que esse é o melhor caminho a percorrer. O TIMESTAMP realmente tem um comportamento estranho e eu nunca escreveria um código com uma limitação de 2038 anos.
Eric
Não importa, eu descobri. Esqueceu de definir o campo para permitir NULL. Não há mais avisos.
Kaji
Gatilhos são maus! Só use-os quando não houver outra maneira de fazer algo. É melhor atualizar para a ID 5.6.x do que usar um gatilho.
ksymeon
4
No MySQL 5.5, o IFNULL não funciona em DATETIME; usando o gatilho acima dateAdded, mostrará tudo '0000-00-00 00:00:00'. Usar isso faz o truque: `FOR EACH ROW IF NEW.dateAdded = 0 THEN SET NEW.dateAdded = NOW (); END IF; `
Kenney
28
Consegui resolver isso usando esta instrução alter na minha tabela que tinha dois campos de data e hora.
Isso funciona como você esperaria que a função now () funcionasse. Inserir nulos ou ignorar os campos created_dt e updated_dt resulta em um valor de carimbo de data e hora perfeito nos dois campos. Qualquer atualização na linha altera o updated_dt. Se você inserir registros através do navegador de consulta MySQL, precisará de mais uma etapa, um gatilho para manipular o created_dt com um novo carimbo de data / hora.
CREATETRIGGER trig_test_table_insert BEFORE INSERTON`test_table`FOR EACH ROWSET NEW.created_dt = NOW();
O gatilho pode ser o que você quiser, assim como a convenção de nomenclatura [trig] _ [my_table_name] _ [insert]
Eu quis dizer, se você inserir registros via navegador de consultas MySQL manualmente através da grade sem uma instrução insert (), o gatilho será necessário. Se você sempre usa uma instrução de inserção, o gatilho é completamente desnecessário.
Ops! Eu quis dizer O gatilho (nome) pode ser o que você quiser, porque o nome do gatilho não afeta a funcionalidade. A maioria das pessoas vai saber isso, mas algumas pessoas novas para MySQL pode não saber ...
Caramba, desculpe pela falta de quebras de linha. Use os pontos e vírgulas para marcar o final de cada linha.
24
Você pode usar gatilhos para fazer esse tipo de coisa.
CREATETABLE`MyTable`(`MyTable_ID` int UNSIGNED NOTNULL AUTO_INCREMENT ,`MyData` varchar(10)NOTNULL,`CreationDate` datetime NULL,`UpdateDate` datetime NULL,PRIMARYKEY(`MyTable_ID`));CREATETRIGGER`MyTable_INSERT` BEFORE INSERTON`MyTable`FOR EACH ROWBEGIN-- Set the creation dateSET new.CreationDate = now();-- Set the udpate dateSet new.UpdateDate = now();END;CREATETRIGGER`MyTable_UPDATE` BEFORE UPDATEON`MyTable`FOR EACH ROWBEGIN-- Set the udpate dateSet new.UpdateDate = now();END;
Para todos aqueles que perderam o coração tentando definir um valor DATETIME padrão no MySQL , eu sei exatamente como você se sente / se sentiu. Então aqui está é:
Não insere a hora não atual. Ele irá inserir '0000-00-00 00:00:00'.
Pit Digger
8
Eu não disse que define a hora atual. Muitas pessoas estavam / estão tentando definir um valor zero padrão, mas simplesmente não funciona. Precisamos eliminar as aspas. Como esse achado causou muito tempo e frustração, pensei em compartilhá-lo com a comunidade. Pessoas como você são responsáveis por usuários que perdem o interesse em compartilhar informações úteis com outras pessoas. Eu seriamente não vejo nenhuma razão para obter um -1! Tanto faz.
Augiwan
3
O mesmo poderia ser alcançado com DATETIME NOT NULL.
Brendan Byrd
Há mais um caractere `dentro do comando sql de exemplo, que não consigo editar, pois é apenas uma edição de um caractere.
Quapka # 24/16
seu código não funcionava para mim, aqui é o que funcionouALTER TABLE zones MODIFY created datetime NOT NULL DEFAULT 0;
Como nota de rodapé , ela é mencionada nos documentos do mysql :
O tipo DATE é usado para valores com uma parte da data, mas sem parte da hora. O MySQL recupera e exibe valores DATE no formato 'AAAA-MM-DD'. O intervalo suportado é de '1000-01-01' a '9999-12-31'.
mesmo se eles também disserem:
Valores inválidos de DATE, DATETIME ou TIMESTAMP são convertidos no valor “zero” do tipo apropriado ('0000-00-00' ou '0000-00-00 00:00:00').
verdade. Eu apenas tentei usar agora e recebi o erro "Código de erro: 1067. Valor padrão inválido.". então qual é a resposta? ;-)
Brian Boatright
Esta é a melhor solução para comprometer as versões 5.5 e 5.6 do MySQL. Para a versão 5.5, pré-determine o valor NOW()e use-o posteriormente para a inserção. Para a versão 5.6, basta definir NOW()como o valor padrão.
Abel Callejo
8
Para todos os que usam a coluna TIMESTAMP como solução, quero destacar a seguinte limitação do manual:
"O tipo de dados TIMESTAMP tem um intervalo de '1970-01-01 00:00:01' UTC a ' 2038-01-19 03:14:07 ' UTC. Possui propriedades variadas, dependendo da versão do MySQL e do SQL modo em que o servidor está sendo executado. Essas propriedades são descritas mais adiante nesta seção. "
Portanto, isso obviamente interromperá seu software em cerca de 28 anos.
Acredito que a única solução no lado do banco de dados é usar gatilhos, como mencionado em outras respostas.
E se o MySQL fosse atualizado daqui a 20 anos e essa limitação fosse removida? Não tenho certeza se isso é possível, mas apenas um pensamento.
NessDan
7
Ao definir gatilhos de múltiplas linhas, é necessário alterar o delimitador, pois o ponto-e-vírgula será considerado pelo compilador MySQL como final do gatilho e gerará erro. por exemplo
DELIMITER //CREATETRIGGER`MyTable_UPDATE` BEFORE UPDATEON`MyTable`FOR EACH ROWBEGIN-- Set the udpate dateSet new.UpdateDate = now();END//
DELIMITER ;
CHANGE também é para renomear o campo. O nome da primeira coluna é o 'antigo', o segundo nome da coluna é o 'novo'. Parece redundante se você não estiver alterando o nome do campo. Se for muito esteticamente desagradável, tente MODIFY.
John Gordon
5
Embora não seja possível fazer isso DATETIMEna definição padrão, você pode simplesmente incorporar uma instrução select na sua instrução insert como esta:
Se você está tentando definir o valor padrão como NOW (), não acho que o MySQL suporte isso. No MySQL, você não pode usar uma função ou expressão como o valor padrão para qualquer tipo de coluna, exceto a coluna do tipo de dados TIMESTAMP, para a qual você pode especificar o CURRENT_TIMESTAMP como padrão.
Se você está tentando definir o valor padrão como NOW (), o MySQL suporta que você precise alterar o tipo dessa coluna TIMESTAMP em vez de DATETIME. TIMESTAMP tem data e hora atuais como padrão .. acho que resolverá o seu problema.
Tomemos, por exemplo, se eu tivesse uma tabela chamada 'site' com uma coluna created_at e update_at que eram DATETIME e precisam do valor padrão de agora, eu poderia executar o seguinte sql para conseguir isso.
ALTER TABLE `site` CHANGE` created_at` `created_at` TIMESTAMP NÃO NULL PADRÃO CURRENT_TIMESTAMP;
ALTER TABLE `site` CHANGE` created_at` `created_at` DATETIME NULL DEFAULT NULL;
ALTER TABLE `site` CHANGE` updated_at` `updated_at` TIMESTAMP NÃO NULL PADRÃO CURRENT_TIMESTAMP;
ALTER TABLE `site` CHANGE` updated_at` `updated_at` DATETIME NULL DEFAULT NULL;
A sequência de instruções é importante porque uma tabela não pode ter duas colunas do tipo TIMESTAMP com valores padrão de CUREENT TIMESTAMP
/************ ROLE ************/
drop table if exists `role`;
create table `role` (
`id_role` bigint(20) unsigned not null auto_increment,
`date_created` datetime,
`date_deleted` datetime,
`name` varchar(35) not null,
`description` text,
primary key (`id_role`)
) comment='';
drop trigger if exists `role_date_created`;
create trigger `role_date_created` before insert
on `role`
for each row
set new.`date_created` = now();
Você pode resolver o carimbo de data / hora padrão. Primeiro, considere qual conjunto de caracteres você está usando, por exemplo, se você tirou utf8 desse conjunto de caracteres, suporta todos os idiomas e, se tirou o lat1, esse conjunto de caracteres suporta apenas o inglês. Próximo setp, se você estiver trabalhando em qualquer projeto, deve conhecer o fuso horário do cliente e selecionar você é o fuso do cliente. Esta etapa é obrigatória.
As colunas DateTime não podem ter valores padrão. Está documentado 'recurso'. Nem todos os desenvolvedores têm acesso para alterar a codificação de caracteres. E definir o servidor para o fuso horário de seus clientes geralmente não é uma possibilidade, especialmente quando os clientes não são todos nativos de uma única área de fuso horário.
Respostas:
EDIÇÃO IMPORTANTE: Agora é possível conseguir isso com os campos DATETIME desde o MySQL 5.6.5 , dê uma olhada no outro post abaixo ...
As versões anteriores não podem fazer isso com DATETIME ...
Mas você pode fazer isso com o TIMESTAMP:
** CAVEAT: se você definir uma coluna com CURRENT_TIMESTAMP ON como padrão, precisará SEMPRE especificar um valor para essa coluna ou o valor será redefinido automaticamente para "now ()" na atualização. Isso significa que, se você não deseja que o valor seja alterado, sua instrução UPDATE deve conter "[nome da sua coluna] = [nome da sua coluna]" (ou algum outro valor) ou o valor se tornará "agora ()". Estranho, mas é verdade. Eu espero que isso ajude. Estou usando o 5.5.56-MariaDB **
fonte
DATE
coluna? (não umadatetime
coluna).Na versão 5.6.5, é possível definir um valor padrão em uma coluna de data e hora e até criar uma coluna que será atualizada quando a linha for atualizada. A definição de tipo:
Referência: http://optimize-this.blogspot.com/2012/04/datetime-default-now-finally-available.html
fonte
dt DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
O MySQL ( antes da versão 5.6.5 ) não permite que funções sejam usadas para os valores padrão de DateTime. O TIMESTAMP não é adequado devido ao seu comportamento estranho e não é recomendado para uso como dados de entrada. (Veja Padrões de tipo de dados MySQL .)
Dito isto, você pode fazer isso criando um gatilho .
Eu tenho uma tabela com um campo DateCreated do tipo DateTime. Eu criei um gatilho nessa tabela "Antes de inserir" e "
SET NEW.DateCreated=NOW()
" e funciona muito bem.Espero que isso ajude alguém.
fonte
IF NEW.created_at IS NOT NULL
Para mim, a abordagem do gatilho funcionou melhor, mas eu encontrei um problema com a abordagem. Considere o gatilho básico para definir um campo de data para a hora atual na inserção:
Isso geralmente é ótimo, mas digamos que você queira definir o campo manualmente via instrução INSERT, da seguinte forma:
O que acontece é que o gatilho substitui imediatamente o valor fornecido para o campo e, portanto, a única maneira de definir um horário não atual é uma instrução UPDATE de acompanhamento - eca! Para substituir esse comportamento quando um valor é fornecido, tente esse gatilho ligeiramente modificado com o operador IFNULL:
Isso fornece o melhor dos dois mundos: você pode fornecer um valor para a coluna da data e ela será demorada; caso contrário, será padronizada para a hora atual. Ainda é um gueto relativo a algo limpo como DEFAULT GETDATE () na definição da tabela, mas estamos chegando mais perto!
fonte
NULL
. Não há mais avisos.dateAdded
, mostrará tudo '0000-00-00 00:00:00'. Usar isso faz o truque: `FOR EACH ROW IF NEW.dateAdded = 0 THEN SET NEW.dateAdded = NOW (); END IF; `Consegui resolver isso usando esta instrução alter na minha tabela que tinha dois campos de data e hora.
Isso funciona como você esperaria que a função now () funcionasse. Inserir nulos ou ignorar os campos created_dt e updated_dt resulta em um valor de carimbo de data e hora perfeito nos dois campos. Qualquer atualização na linha altera o updated_dt. Se você inserir registros através do navegador de consulta MySQL, precisará de mais uma etapa, um gatilho para manipular o created_dt com um novo carimbo de data / hora.
O gatilho pode ser o que você quiser, assim como a convenção de nomenclatura [trig] _ [my_table_name] _ [insert]
fonte
Você pode usar gatilhos para fazer esse tipo de coisa.
fonte
Para todos aqueles que perderam o coração tentando definir um valor DATETIME padrão no MySQL , eu sei exatamente como você se sente / se sentiu. Então aqui está é:
Observe cuidadosamente que não adicionei aspas simples / aspas duplas ao redor do 0
Eu estou literalmente pulando depois de resolver este: D
fonte
ALTER TABLE zones MODIFY created datetime NOT NULL DEFAULT 0;
O MySQL 5.6 corrigiu esse problema .
fonte
Se você já criou a tabela, poderá usar
Para alterar o valor padrão para a hora atual
Para alterar o valor padrão para '2015-05-11 13:01:01'
fonte
esta é realmente uma notícia terrível. aqui está uma longa solicitação de bug / recurso pendente para isso . essa discussão também fala sobre as limitações do tipo de dados timestamp.
Estou seriamente me perguntando qual é o problema com a implementação dessa coisa.
fonte
Estou executando o MySql Server 5.7.11 e esta frase:
não está funcionando Mas o seguinte:
simplesmente funciona .
Como nota de rodapé , ela é mencionada nos documentos do mysql :
mesmo se eles também disserem:
fonte
Você pode usar now () para definir o valor de uma coluna datetime, mas lembre-se de que não pode usá-lo como valor padrão.
fonte
NOW()
e use-o posteriormente para a inserção. Para a versão 5.6, basta definirNOW()
como o valor padrão.Para todos os que usam a coluna TIMESTAMP como solução, quero destacar a seguinte limitação do manual:
http://dev.mysql.com/doc/refman/5.0/en/datetime.html
"O tipo de dados TIMESTAMP tem um intervalo de '1970-01-01 00:00:01' UTC a ' 2038-01-19 03:14:07 ' UTC. Possui propriedades variadas, dependendo da versão do MySQL e do SQL modo em que o servidor está sendo executado. Essas propriedades são descritas mais adiante nesta seção. "
Portanto, isso obviamente interromperá seu software em cerca de 28 anos.
Acredito que a única solução no lado do banco de dados é usar gatilhos, como mencionado em outras respostas.
fonte
Ao definir gatilhos de múltiplas linhas, é necessário alterar o delimitador, pois o ponto-e-vírgula será considerado pelo compilador MySQL como final do gatilho e gerará erro. por exemplo
fonte
Aqui está como fazê-lo no MySQL 5.1:
Não faço idéia por que você deve digitar o nome da coluna duas vezes.
fonte
Embora não seja possível fazer isso
DATETIME
na definição padrão, você pode simplesmente incorporar uma instrução select na sua instrução insert como esta:Observe a falta de aspas ao redor da mesa.
Para o MySQL 5.5
fonte
Se você está tentando definir o valor padrão como NOW (), não acho que o MySQL suporte isso. No MySQL, você não pode usar uma função ou expressão como o valor padrão para qualquer tipo de coluna, exceto a coluna do tipo de dados TIMESTAMP, para a qual você pode especificar o CURRENT_TIMESTAMP como padrão.
fonte
Eu acho simples no mysql, uma vez que o mysql é a função embutida chamada now (), que fornece o tempo atual (hora dessa inserção).
Portanto, sua consulta deve ser semelhante
Obrigado.
fonte
Na consulta acima, para criar 'testtable', usei '1999-12-12 12:12:12' como valor padrão para a coluna DATETIME
colname
fonte
Use o seguinte código
fonte
Se você está tentando definir o valor padrão como NOW (), o MySQL suporta que você precise alterar o tipo dessa coluna TIMESTAMP em vez de DATETIME. TIMESTAMP tem data e hora atuais como padrão .. acho que resolverá o seu problema.
fonte
Tomemos, por exemplo, se eu tivesse uma tabela chamada 'site' com uma coluna created_at e update_at que eram DATETIME e precisam do valor padrão de agora, eu poderia executar o seguinte sql para conseguir isso.
A sequência de instruções é importante porque uma tabela não pode ter duas colunas do tipo TIMESTAMP com valores padrão de CUREENT TIMESTAMP
fonte
Este é o meu exemplo de gatilho:
fonte
Trabalhando bem com o MySQL 8.x
fonte
Você pode resolver o carimbo de data / hora padrão. Primeiro, considere qual conjunto de caracteres você está usando, por exemplo, se você tirou utf8 desse conjunto de caracteres, suporta todos os idiomas e, se tirou o lat1, esse conjunto de caracteres suporta apenas o inglês. Próximo setp, se você estiver trabalhando em qualquer projeto, deve conhecer o fuso horário do cliente e selecionar você é o fuso do cliente. Esta etapa é obrigatória.
fonte