@GhostInTheSecureShell tiene la misión de instalarlo, al menos en Debian, pero definitivamente es una característica increíble. ¡Creo que eventualmente todas estas "dos CURRENT_TIMESTAMP" serán aliviadas!
Marc DiMillo
ahora es función () o puede hacerlo con la configuración predeterminada en el nivel de columna.
Anshul Sharma
Respuestas:
862
EDICIÓN IMPORTANTE:
ahora es posible lograr esto con los campos DATETIME desde MySQL 5.6.5 , eche un vistazo a la otra publicación a continuación ...
Las versiones anteriores no pueden hacer eso con DATETIME ...
Pero puedes hacerlo con 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: SI define una columna con CURRENT_TIMESTAMP ON por defecto, SIEMPRE necesitará especificar un valor para esta columna o el valor se restablecerá automáticamente a "now ()" en la actualización. Esto significa que si no desea que el valor cambie, su instrucción UPDATE debe contener "[su nombre de columna] = [su nombre de columna]" (o algún otro valor) o el valor se convertirá en "ahora ()". Extraño, pero cierto. Espero que esto ayude. Estoy usando 5.5.56-MariaDB **
Es importante tener en cuenta que la fecha y hora tiene un rango de 1000-9999, pero el rango de la marca de tiempo es solo 1970-2038 . Esto puede ser un problema si su sistema tiene que almacenar fechas de nacimiento, o si tiene que manejar algo como el plan de pago para una hipoteca a 30 años. dev.mysql.com/doc/refman/5.0/en/datetime.html
Kip
13
Tenga cuidado también con la marca de tiempo, ya que se actualiza automáticamente mágicamente ... vea la próxima respuesta stackoverflow.com/a/1483959/233906
Cerber
66
Que es posible a partir de la versión 5.6.5, véase la respuesta de Gustav continuación (Me doy cuenta de que su respuesta fue publicada cuando MySQL todavía era 5.0!)
e2-e4
44
@Kip, Hola, ¿es posible tener un valor predeterminado para una DATEcolumna? (no una datetimecolumna)
Sajib Acharya
ti no parece posible para las columnas DATE: debe usar el tipo de datos DATETIME
Fabio Napodano
599
En la versión 5.6.5, es posible establecer un valor predeterminado en una columna de fecha y hora, e incluso crear una columna que se actualizará cuando se actualice la fila. La definición del tipo:
Valor predeterminado no válido para 'menu_creation_time'
Fernando Trindade
2
@FernandoTrindade Necesita MySQL versión 5.6.5 o posterior. Puedes verlo trabajando aquí: sqlfiddle.com/#!9/dd2be
Gustav Bertram
1
@GustavBertram, estoy usando la versión 5.6.22, pero aún recibí el siguiente error: CREATE TABLE tbl (InsertDate DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, UpdateDate TIMESTAMP NULL ON UPDATE CURRENT_TIMESTAMP (6)); Código de error: 1294. Cláusula ON UPDATE no válida para la columna 'UpdateDate'
Manish Sapkal
@ManishSapkal Estás utilizando un TIMESTAMP, no un DATETIME. Además, no lo hagas NULL.
Tengo una tabla con un campo DateCreated de tipo DateTime. Creé un disparador en esa tabla "Antes de insertar" y " SET NEW.DateCreated=NOW()" y funciona muy bien.
CREATE TRIGGER trigger_foo_SetCreatedAt ANTES DE INSERTAR EN foo PARA CADA FILA SET NEW.created_at = UTC_TIMESTAMP ();
kgriffs
55
Probablemente sea mejor usar una marca de tiempo que un disparador para la cordura futura (mantenimiento). Este es un caso de uso demasiado trivial para un desencadenante, aunque es una solución.
getWeberForStackExchange
8
Probablemente solo desee establecer el valor predeterminadoIF NEW.created_at IS NOT NULL
Petr Peller, el
132
Para mí, el enfoque de disparo ha funcionado mejor, pero encontré un inconveniente con el enfoque. Considere el disparador básico para establecer un campo de fecha a la hora actual en la inserción:
CREATETRIGGER myTable_OnInsert BEFORE INSERTON`tblMyTable`FOR EACH ROWSET NEW.dateAdded = NOW();
Esto suele ser genial, pero digamos que desea establecer el campo manualmente a través de la instrucción INSERT, así:
Lo que sucede es que el activador sobrescribe inmediatamente el valor proporcionado para el campo, por lo que la única forma de establecer una hora no actual es una declaración de ACTUALIZACIÓN de seguimiento: ¡qué asco! Para anular este comportamiento cuando se proporciona un valor, pruebe este disparador ligeramente modificado con el operador IFNULL:
CREATETRIGGER myTable_OnInsert BEFORE INSERTON`tblMyTable`FOR EACH ROWSET NEW.dateAdded = IFNULL(NEW.dateAdded, NOW());
Esto brinda lo mejor de ambos mundos: puede proporcionar un valor para su columna de fecha y tomará, y de lo contrario, se establecerá de manera predeterminada a la hora actual. Todavía es un ghetto en relación con algo limpio como DEFAULT GETDATE () en la definición de la tabla, ¡pero nos estamos acercando!
+1 para reconocer la advertencia con la sobrescritura de valores explícitos de usuario en la inserción.
Kip
2
Personalmente, creo que este es el mejor camino a seguir. TIMESTAMP tiene un comportamiento extraño y nunca escribiría código que tenga una limitación de 2038 años.
Eric
No importa, lo descubrí. Olvidé configurar el campo para permitir NULL. No hay advertencias más.
Kaji
¡Los disparadores son malvados! Solo úselas cuando no haya otra forma de hacer algo. Es mejor actualizar a 5.6.x id que puede usar que un disparador.
ksymeon
44
En MySQL 5.5, IFNULL no funciona en DATETIME; usando el disparador anterior, dateAddedse mostrarán todos los '0000-00-00 00:00:00'. Usar esto hace el truco: `PARA CADA FILA SI ES NUEVO. DateAdded = 0 LUEGO ESTABLECE NEW.dateAdded = NOW (); END IF; `
Kenney
28
Pude resolver esto usando esta declaración alter en mi tabla que tenía dos campos de fecha y hora.
Esto funciona como es de esperar que funcione la función now (). Insertar nulos o ignorar los campos created_dt y updated_dt da como resultado un valor de marca de tiempo perfecto en ambos campos. Cualquier actualización de la fila cambia el updated_dt. Si inserta registros a través del navegador de consultas MySQL, necesita un paso más, un activador para manejar el created_dt con una nueva marca de tiempo.
CREATETRIGGER trig_test_table_insert BEFORE INSERTON`test_table`FOR EACH ROWSET NEW.created_dt = NOW();
El desencadenador puede ser lo que quieras Simplemente me gusta la convención de nomenclatura [trig] _ [my_table_name] _ [insert]
Quise decir, si inserta registros a través del navegador de consultas MySQL manualmente a través de la cuadrícula sin una instrucción insert (), se necesita el desencadenante. Si siempre usa una instrucción de inserción, el desencadenante es completamente innecesario.
Whoops! Quise decir que El desencadenante (nombre) puede ser lo que quieras porque el nombre del desencadenante no afecta en absoluto la funcionalidad. La mayoría de la gente va a saber que, pero algunas personas nuevas a MySQL puede no saber ...
Ay, perdón por la falta de saltos de línea. Usa los punto y coma para marcar el final de cada línea.
24
Puedes usar disparadores para hacer este tipo de cosas.
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 aquellos que se desanimaron tratando de establecer un valor DATETIME predeterminado en MySQL , sé exactamente cómo se siente / sintió. Entonces aquí está:
No inserta ni la hora actual. Insertará '0000-00-00 00:00:00'.
Pit Digger
8
No dije que establezca la hora actual. Muchas personas estaban / están tratando de establecer un valor cero predeterminado, pero simplemente no funciona. Necesitamos eliminar las comillas. Como este hallazgo causó mucho tiempo y frustración, pensé en compartirlo con la comunidad. Las personas como usted son responsables de que los usuarios pierdan interés en compartir información útil con otras personas. En serio, no veo ninguna razón para obtener un -1. Lo que sea.
Augiwan
3
Lo mismo podría lograrse con DATETIME NOT NULL.
Brendan Byrd
Hay un `carácter más dentro del comando sql de ejemplo, que no puedo editar, ya que es solo una edición de carácter.
Quapka
su código no funcionó para mí, esto es lo que funcionóALTER TABLE zones MODIFY created datetime NOT NULL DEFAULT 0;
El tipo DATE se usa para valores con una parte de fecha pero sin parte de tiempo. MySQL recupera y muestra los valores de FECHA en formato 'AAAA-MM-DD'. El rango admitido es '1000-01-01' a '9999-12-31'.
incluso si también dicen:
Los valores DATE, DATETIME o TIMESTAMP no válidos se convierten al valor "cero" del tipo apropiado ('0000-00-00' o '0000-00-00 00:00:00').
cierto. Acabo de intentar usar ahora y recibí un error "Código de error: 1067. Valor predeterminado no válido" Entonces, ¿cuál es la respuesta? ;-)
Brian Boatright
Esta es la mejor solución para comprometer las versiones de MySQL 5.5 y 5.6. Para la versión 5.5, predetermine el valor NOW()y utilícelo más tarde para la inserción. Para la versión 5.6, simplemente establezca NOW()el valor predeterminado.
Abel Callejo
8
Para todos los que usan la columna TIMESTAMP como solución, quiero secundar la siguiente limitación del manual:
"El tipo de datos TIMESTAMP tiene un rango de '1970-01-01 00:00:01' UTC a ' 2038-01-19 03:14:07 ' UTC. Tiene propiedades variables, dependiendo de la versión de MySQL y el SQL modo en el que se ejecuta el servidor. Estas propiedades se describen más adelante en esta sección ".
Obviamente, esto romperá su software en aproximadamente 28 años.
Creo que la única solución en el lado de la base de datos es usar disparadores como se menciona en otras respuestas.
¿Qué pasa si MySQL se actualizó dentro de 20 años y se eliminó esa limitación? No estoy seguro de si eso es posible, pero solo un pensamiento.
NessDan
7
Al definir disparadores de líneas múltiples, uno tiene que cambiar el delimitador, ya que el compilador MySQL tomará el punto y coma como final del disparador y generará un error. p.ej
DELIMITER //CREATETRIGGER`MyTable_UPDATE` BEFORE UPDATEON`MyTable`FOR EACH ROWBEGIN-- Set the udpate dateSet new.UpdateDate = now();END//
DELIMITER ;
CAMBIO también es para renombrar el campo. El nombre de la primera columna es el "antiguo", el nombre de la segunda columna es el "nuevo". Parece redundante si no está cambiando el nombre del campo. Si es demasiado desagradable estéticamente, intente MODIFICAR.
John Gordon
5
Si bien no puede hacer esto con DATETIMEla definición predeterminada, simplemente puede incorporar una declaración de selección en su declaración de inserción de esta manera:
Si está intentando establecer el valor predeterminado como AHORA (), no creo que MySQL lo admita. En MySQL, no puede usar una función o una expresión como valor predeterminado para ningún tipo de columna, excepto para la columna de tipo de datos TIMESTAMP, para la cual puede especificar CURRENT_TIMESTAMP como predeterminado.
Si está intentando establecer el valor predeterminado como AHORA (), MySQL admite que debe cambiar el tipo de esa columna TIMESTAMP en lugar de DATETIME. TIMESTAMP tiene la fecha y hora actuales como predeterminadas ... creo que resolverá su problema ...
Tomemos, por ejemplo, si tuviera una tabla llamada 'sitio' con una columna created_at y update_at que fueran DATETIME y necesiten el valor predeterminado de ahora, podría ejecutar el siguiente sql para lograr esto.
ALTER TABLE `site` CHANGE` created_at` `created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;
ALTER TABLE `site` CHANGE` created_at` `created_at` DATETIME NULL DEFAULT NULL;
ALTER TABLE `site` CHANGE` updated_at` `updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;
ALTER TABLE `site` CHANGE` updated_at` `updated_at` DATETIME NULL DEFAULT NULL;
La secuencia de declaraciones es importante porque una tabla no puede tener dos columnas de tipo TIMESTAMP con valores predeterminados 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();
Puede resolver la marca de tiempo predeterminada. Primero considere qué juego de caracteres está utilizando, por ejemplo, si tomó utf8, este juego de caracteres admite todos los idiomas y si tomó late1 este juego de caracteres solo admite inglés. Luego, si está trabajando en algún proyecto, debe conocer la zona horaria del cliente y seleccionar la zona del cliente. Este paso es obligatorio.
Las columnas DateTime no pueden tener valores predeterminados. Está documentado 'característica'. No todos los desarrolladores tienen acceso para cambiar su codificación de caracteres. Y configurar el servidor en la zona horaria de sus clientes generalmente no es una posibilidad, especialmente cuando los clientes no son todos nativos de un área de zona horaria única.
Respuestas:
EDICIÓN IMPORTANTE: ahora es posible lograr esto con los campos DATETIME desde MySQL 5.6.5 , eche un vistazo a la otra publicación a continuación ...
Las versiones anteriores no pueden hacer eso con DATETIME ...
Pero puedes hacerlo con TIMESTAMP:
** CAVEAT: SI define una columna con CURRENT_TIMESTAMP ON por defecto, SIEMPRE necesitará especificar un valor para esta columna o el valor se restablecerá automáticamente a "now ()" en la actualización. Esto significa que si no desea que el valor cambie, su instrucción UPDATE debe contener "[su nombre de columna] = [su nombre de columna]" (o algún otro valor) o el valor se convertirá en "ahora ()". Extraño, pero cierto. Espero que esto ayude. Estoy usando 5.5.56-MariaDB **
fuente
DATE
columna? (no unadatetime
columna)En la versión 5.6.5, es posible establecer un valor predeterminado en una columna de fecha y hora, e incluso crear una columna que se actualizará cuando se actualice la fila. La definición del tipo:
Referencia: http://optimize-this.blogspot.com/2012/04/datetime-default-now-finally-available.html
fuente
dt DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
MySQL ( antes de la versión 5.6.5 ) no permite que se usen funciones para los valores predeterminados de DateTime. TIMESTAMP no es adecuado debido a su comportamiento extraño y no se recomienda su uso como datos de entrada. (Consulte Valores predeterminados del tipo de datos MySQL ).
Dicho esto, puedes lograr esto creando un Trigger .
Tengo una tabla con un campo DateCreated de tipo DateTime. Creé un disparador en esa tabla "Antes de insertar" y "
SET NEW.DateCreated=NOW()
" y funciona muy bien.Espero que esto ayude a alguien.
fuente
IF NEW.created_at IS NOT NULL
Para mí, el enfoque de disparo ha funcionado mejor, pero encontré un inconveniente con el enfoque. Considere el disparador básico para establecer un campo de fecha a la hora actual en la inserción:
Esto suele ser genial, pero digamos que desea establecer el campo manualmente a través de la instrucción INSERT, así:
Lo que sucede es que el activador sobrescribe inmediatamente el valor proporcionado para el campo, por lo que la única forma de establecer una hora no actual es una declaración de ACTUALIZACIÓN de seguimiento: ¡qué asco! Para anular este comportamiento cuando se proporciona un valor, pruebe este disparador ligeramente modificado con el operador IFNULL:
Esto brinda lo mejor de ambos mundos: puede proporcionar un valor para su columna de fecha y tomará, y de lo contrario, se establecerá de manera predeterminada a la hora actual. Todavía es un ghetto en relación con algo limpio como DEFAULT GETDATE () en la definición de la tabla, ¡pero nos estamos acercando!
fuente
NULL
. No hay advertencias más.dateAdded
se mostrarán todos los '0000-00-00 00:00:00'. Usar esto hace el truco: `PARA CADA FILA SI ES NUEVO. DateAdded = 0 LUEGO ESTABLECE NEW.dateAdded = NOW (); END IF; `Pude resolver esto usando esta declaración alter en mi tabla que tenía dos campos de fecha y hora.
Esto funciona como es de esperar que funcione la función now (). Insertar nulos o ignorar los campos created_dt y updated_dt da como resultado un valor de marca de tiempo perfecto en ambos campos. Cualquier actualización de la fila cambia el updated_dt. Si inserta registros a través del navegador de consultas MySQL, necesita un paso más, un activador para manejar el created_dt con una nueva marca de tiempo.
El desencadenador puede ser lo que quieras Simplemente me gusta la convención de nomenclatura [trig] _ [my_table_name] _ [insert]
fuente
Puedes usar disparadores para hacer este tipo de cosas.
fuente
Para todos aquellos que se desanimaron tratando de establecer un valor DATETIME predeterminado en MySQL , sé exactamente cómo se siente / sintió. Entonces aquí está:
Observe cuidadosamente que no he agregado comillas simples / comillas dobles alrededor del 0
Estoy literalmente saltando después de resolver este: D
fuente
ALTER TABLE zones MODIFY created datetime NOT NULL DEFAULT 0;
MySQL 5.6 ha solucionado este problema .
fuente
Si ya ha creado la tabla, puede usar
Para cambiar el valor predeterminado a la fecha y hora actual
Para cambiar el valor predeterminado a '2015-05-11 13:01:01'
fuente
Esta es una noticia terrible. Aquí hay una solicitud de error / función pendiente por mucho tiempo para esto . esa discusión también habla sobre las limitaciones del tipo de datos de marca de tiempo.
Me pregunto seriamente cuál es el problema con implementar esto.
fuente
Estoy ejecutando MySql Server 5.7.11 y esta oración:
es no trabajar. Pero lo siguiente:
solo funciona .
Como nota al margen , se menciona en los documentos de mysql :
incluso si también dicen:
fuente
Puede usar now () para establecer el valor de una columna de fecha y hora, pero tenga en cuenta que no puede usarlo como valor predeterminado.
fuente
NOW()
y utilícelo más tarde para la inserción. Para la versión 5.6, simplemente establezcaNOW()
el valor predeterminado.Para todos los que usan la columna TIMESTAMP como solución, quiero secundar la siguiente limitación del manual:
http://dev.mysql.com/doc/refman/5.0/en/datetime.html
"El tipo de datos TIMESTAMP tiene un rango de '1970-01-01 00:00:01' UTC a ' 2038-01-19 03:14:07 ' UTC. Tiene propiedades variables, dependiendo de la versión de MySQL y el SQL modo en el que se ejecuta el servidor. Estas propiedades se describen más adelante en esta sección ".
Obviamente, esto romperá su software en aproximadamente 28 años.
Creo que la única solución en el lado de la base de datos es usar disparadores como se menciona en otras respuestas.
fuente
Al definir disparadores de líneas múltiples, uno tiene que cambiar el delimitador, ya que el compilador MySQL tomará el punto y coma como final del disparador y generará un error. p.ej
fuente
Aquí se explica cómo hacerlo en MySQL 5.1:
No tengo idea de por qué debe ingresar el nombre de la columna dos veces.
fuente
Si bien no puede hacer esto con
DATETIME
la definición predeterminada, simplemente puede incorporar una declaración de selección en su declaración de inserción de esta manera:Tenga en cuenta la falta de comillas alrededor de la mesa.
Para MySQL 5.5
fuente
Si está intentando establecer el valor predeterminado como AHORA (), no creo que MySQL lo admita. En MySQL, no puede usar una función o una expresión como valor predeterminado para ningún tipo de columna, excepto para la columna de tipo de datos TIMESTAMP, para la cual puede especificar CURRENT_TIMESTAMP como predeterminado.
fuente
Creo que es simple en mysql ya que mysql es la función incorporada llamada now () que proporciona la hora actual (hora de esa inserción).
Entonces su consulta debería verse de manera similar
Gracias.
fuente
En la consulta anterior para crear 'testtable', usé '1999-12-12 12:12:12' como valor predeterminado para la columna DATETIME
colname
fuente
Usa el siguiente código
fuente
Si está intentando establecer el valor predeterminado como AHORA (), MySQL admite que debe cambiar el tipo de esa columna TIMESTAMP en lugar de DATETIME. TIMESTAMP tiene la fecha y hora actuales como predeterminadas ... creo que resolverá su problema ...
fuente
Tomemos, por ejemplo, si tuviera una tabla llamada 'sitio' con una columna created_at y update_at que fueran DATETIME y necesiten el valor predeterminado de ahora, podría ejecutar el siguiente sql para lograr esto.
La secuencia de declaraciones es importante porque una tabla no puede tener dos columnas de tipo TIMESTAMP con valores predeterminados de CUREENT TIMESTAMP
fuente
Este es mi ejemplo de activación:
fuente
Trabajando bien con MySQL 8.x
fuente
Puede resolver la marca de tiempo predeterminada. Primero considere qué juego de caracteres está utilizando, por ejemplo, si tomó utf8, este juego de caracteres admite todos los idiomas y si tomó late1 este juego de caracteres solo admite inglés. Luego, si está trabajando en algún proyecto, debe conocer la zona horaria del cliente y seleccionar la zona del cliente. Este paso es obligatorio.
fuente