Error en MySQL al establecer el valor predeterminado para DATE o DATETIME

124

Estoy ejecutando MySql Server 5.7.11 y esta oración:

updated datetime NOT NULL DEFAULT '0000-00-00 00:00:00'

no está funcionando. Dando el error:

ERROR 1067 (42000): Invalid default value for 'updated'

Pero lo siguiente:

updated datetime NOT NULL DEFAULT '1000-01-01 00:00:00'

simplemente funciona .

El mismo caso para DATE.

Como nota al margen , se menciona en los documentos de MySQL :

El tipo DATE se utiliza para valores con una parte de fecha pero sin una 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'.

aunque también digan:

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').

Teniendo también en cuenta la segunda cita de la documentación de MySQL, ¿alguien podría hacerme saber por qué da ese error?

Evhz
fuente
11
¿Por qué querrías un valor predeterminado que obviamente no tiene sentido? Si se desconoce la fecha, para eso es exactamente NULL.
Tom H
Como nota: esto funciona en la versión 5.6 en SQL Fiddle - sqlfiddle.com/#!9/02c98 .
Gordon Linoff
@Karlos revisa la respuesta actualizada.
geeksal

Respuestas:

209

El error se debe al modo sql, que puede ser un modo estricto según la última documentación de MYSQL 5.7

La documentación de MySQL 5.7 dice :

El modo estricto afecta si el servidor permite '0000-00-00' como fecha válida: si el modo estricto no está habilitado, se permite '0000-00-00' y las inserciones no producen ninguna advertencia. Si el modo estricto está habilitado, '0000-00-00' no está permitido y las inserciones producen un error, a menos que también se proporcione IGNORE. Para INSERT IGNORE y UPDATE IGNORE, se permite '0000-00-00' y las inserciones producen una advertencia.

Para comprobar el modo MYSQL

SELECT @@GLOBAL.sql_mode global, @@SESSION.sql_mode session

Inhabilitando el modo STRICT_TRANS_TABLES

Sin embargo, para permitir el formato 0000-00-00 00:00:00 , debe deshabilitar el modo STRICT_TRANS_TABLES en el archivo de configuración mysql o por comando

Por orden

SET sql_mode = '';

o

SET GLOBAL sql_mode = '';

El uso de la palabra clave GLOBALrequiere súper prejuicios y afecta las operaciones que todos los clientes conectan a partir de ese momento.

si lo anterior no funciona, vaya a /etc/mysql/my.cnf(según ubuntu) y comenteSTRICT_TRANS_TABLES

Además, si desea establecer permanentemente el modo SQL al arrancar el servidor a continuación, incluir SET sql_mode=''en my.cnfel Linux o MacOS. Para Windows, esto debe hacerse en my.iniarchivo.

Nota

Sin embargo, el modo estricto no está habilitado por defecto en MYSQL 5.6. Por lo tanto, no produce el error según la documentación de MYSQL 6 que dice

MySQL le permite almacenar un valor "cero" de '0000-00-00' como una "fecha ficticia". En algunos casos, esto es más conveniente que usar valores NULL y usa menos datos y espacio de índice. Para no permitir '0000-00-00', habilite el modo SQL NO_ZERO_DATE.

ACTUALIZAR

Con respecto al asunto del error como lo dijo @ Dylan-Su:

No creo que este sea el problema, ya que la forma en que MYSQL evoluciona con el tiempo debido a que algunas cosas se cambian en función de la mejora adicional del producto.

Sin embargo, tengo otro informe de error relacionado con la NOW()función

El campo de fecha y hora no acepta el valor predeterminado AHORA ()

Otra nota útil [consulte Inicialización y actualización automáticas para TIMESTAMP y DATETIME ]

A partir de MySQL 5.6.5, las columnas TIMESTAMP y DATETIME se pueden inicializar y actualizar automáticamente a la fecha y hora actuales (es decir, la marca de tiempo actual). Antes de 5.6.5, esto es cierto solo para TIMESTAMP, y como máximo para una columna TIMESTAMP por tabla. Las siguientes notas describen primero la inicialización y actualización automática para MySQL 5.6.5 y posteriores, luego las diferencias para las versiones anteriores a 5.6.5.

Actualización sobre NO_ZERO_DATE

A partir de MySQL a partir de 5.7.4, este modo está obsoleto. Para la versión anterior, debe comentar la línea respectiva en el archivo de configuración. Consulte la documentación de MySQL 5.7 el NO_ZERO_DATE

geek
fuente
5
ACTUALIZAR IGNORAR es lo que estaba buscando 👍🏻
Afanasii Kurakin
2
Incorrecto. Tengo STRICT_TRANS_TABLESpara mis dos instancias de MySQL, local y servidor. Sin embargo, puedo insertar fácilmente 0000-00-00en mi instancia local, pero no puedo en mi instancia de servidor; se produce un error. ¿Por qué? Porque la configuración de MySQL de mi servidor se ha NO_ZERO_DATEhabilitado. Y mi local no lo tiene.
Verde
ok @Green averiguaré y actualizaré la respuesta si corresponde
geeksal
4
En mi caso, 'SET sql_mode = ""' no funcionó. 'SET GLOBAL sql_mode = "";' hizo el trabajo por mí.
arjen Stens
También NO_ZERO_DATEdebe eliminarse
Preshan Pradeepa
18

Tuve este error con WAMP 3.0.6 con MySql 5.7.14.

Solucion :

cambie la línea 70 (si su archivo ini está intacto) en el c:\wamp\bin\mysql\mysql5.7.14\my.iniarchivo de

sql-mode= "STRICT_ALL_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_ZERO_DATE,NO_ZERO_IN_DATE,NO_AUTO_CREATE_USER"

a

sql-mode="ERROR_FOR_DIVISION_BY_ZERO,NO_ZERO_DATE,NO_ZERO_IN_DATE,NO_AUTO_CREATE_USER"

y reinicie todos los servicios.

Esto desactivará el modo estricto. Según la documentación, "modo estricto" significa un modo con uno o ambos STRICT_TRANS_TABLESo STRICT_ALL_TABLEShabilitado. La documentación dice:

"El modo SQL predeterminado en MySQL 5.7 incluye estos modos: ONLY_FULL_GROUP_BY, STRICT_TRANS_TABLES, NO_ZERO_IN_DATE, NO_ZERO_DATE, ERROR_FOR_DIVISION_BY_ZERO, NO_AUTO_CREATE_USER y NO_SUBTITUTION_SUBE."

bg17aw
fuente
14

Entré en una situación en la que los datos se mezclaban entre NULL y 0000-00-00 para un campo de fecha. Pero no sabía cómo actualizar el '0000-00-00' a NULL, porque

 update my_table set my_date_field=NULL where my_date_field='0000-00-00'

ya no está permitido. Mi solución fue bastante simple:

update my_table set my_date_field=NULL where my_date_field<'1000-01-01'

porque todos los my_date_fieldvalores incorrectos (sean fechas correctas o no) eran anteriores a esta fecha.

Martín T.
fuente
2
Solución rápida perfecta. De hecho, también podría usar, <'0000-01-01'ya que, por supuesto, es una fecha válida.
Ricky McMaster
5

Problema de sintaxis de configuración

En algunas versiones de MYSQL (probada 5.7. *) En sistemas * nix, debe usar esta sintaxis:

[mysqld]

sql-mode="NO_BACKSLASH_ESCAPES,STRICT_TRANS_TABLE,NO_ENGINE_SUBSTITUTION"

Estos no funcionarán:

guión sin comillas

sql-mode=NO_ENGINE_SUBSTITUTION

subrayado sin comillas

sql_mode=NO_ENGINE_SUBSTITUTION

subrayado y comillas

sql_mode="NO_ENGINE_SUBSTITUTION"

Una revisión más completa de los valores de configuración y el modo sql:

Cómo configurar banderas permanentes del modo Sql

Heroselohim
fuente
5

Primero seleccione la sesión actual sql_mode:

SELECT @@SESSION.sql_mode;

Entonces obtendrás algo como ese valor predeterminado :

'ONLY_FULL_GROUP_BY, STRICT_TRANS_TABLES, NO_ZERO_IN_DATE, NO_ZERO_DATE, ERROR_FOR_DIVISION_BY_ZERO, NO_AUTO_CREATE_USER, NO_ENGINE_SUBSTITUTION'

y luego configurar sql_modesin 'NO_ZERO_DATE':

SET SESSION sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';

Si tienes subvenciones, puedes hacerlo también para GLOBAL:

SELECT @@GLOBAL.sql_mode;
SET GLOBAL sql_mode = '...';
simhumileco
fuente
4

Solo agrega la línea: sql_mode = "NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"

archivo interior: /etc/mysql/mysql.conf.d/mysqld.cnf

luego sudo service mysql restart

ferreidon aftahi
fuente
1
Funciona para 5.7.23.
user2513149
1
Probablemente sugeriría SELECT @@SESSION.sql_mode;primero, y que eliminen NO_ZERO_IN_DATE, NO_ZERO_DATE y STRICT_TRANS_TABLES de lo que le brinda. De esa manera, mantendrá cualquier otra configuración que haya habilitado. Tenía mucho más que solo esos dos elementos configurados para mi modo SQL. No sé qué hacen todos, pero no quiero arriesgarme a eliminarlos en este momento.
Radley Sustaire
2

Funciona para 5.7.8:

mysql> create table t1(updated datetime NOT NULL DEFAULT '0000-00-00 00:00:00');
Query OK, 0 rows affected (0.01 sec)

mysql> show create table t1;
+-------+-------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table                                                                                                            |
+-------+-------------------------------------------------------------------------------------------------------------------------+
| t1    | CREATE TABLE `t1` (
  `updated` datetime NOT NULL DEFAULT '0000-00-00 00:00:00'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 |
+-------+-------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> select version();
+-----------+
| version() |
+-----------+
| 5.7.8-rc  |
+-----------+
1 row in set (0.00 sec)

Puede crear un SQLFiddle para recrear su problema.

http://sqlfiddle.com/

Si funciona para MySQL 5.6 y 5.7.8, pero falla en 5.7.11. Entonces probablemente sea un error de regresión para 5.7.11.

Dylan Su
fuente
1

Para resolver el problema con MySQL Workbench (después de aplicar la solución en el lado del servidor):

Elimine SQL_MODE a TRADITIONAL en el panel de preferencias.

ingrese la descripción de la imagen aquí

Vindic
fuente
1

Esta respuesta es solo para MySQL 5.7:

Lo mejor no está realmente en blanco en sql_mode, en su lugar use en PHP una variable de sesión con:

SET SESSION sql_mode= 'ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'

Así que al menos mantienes los otros valores predeterminados.

Es una locura que la documentación de mysql no esté clara, necesita eliminar estos valores defectuosos en sql_mode:

NO_ZERO_IN_DATE, NO_ZERO_DATE, lo entiendo, pero en futuras versiones esto será descontinuado.

STRICT_ALL_TABLES, con esto, antes de que se ignoren los parámetros, por lo que también debe eliminarlo.

Finalmente TRADICIONAL también, pero la documentación habla de este parámetro: “dar un error en lugar de una advertencia” al insertar un valor incorrecto en una columna ”, con este parámetro no se insertan fechas con valores cero, pero sin sí.

MySQL no está realmente organizado con estos parámetros y combinaciones.

apilado
fuente
0

Combinaciones de opciones para mysql Ver 14.14 Distrib 5.7.18, for Linux (x86_64) .

No lanza:

STRICT_TRANS_TABLES + NO_ZERO_DATE

Lanza:

STRICT_TRANS_TABLES + NO_ZERO_IN_DATE

Mi configuración en /etc/mysql/my.cnfUbuntu:

[mysqld]
sql_mode = "STRICT_TRANS_TABLES,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
Verde
fuente
0
set global sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';
Aris tri jaka
fuente
0

En el directorio xamp / mysql / bin Abra "my.ini" y cambie la línea: Sql_node por ->

"sql_mode = NO_ENGINE_SUBSTITUTION, NO_ZERO_DATE"

QUITAR "NO_ZERO_IN_DATE"

leandro ramos
fuente
Bienvenido a stackoverflow, use el formato de código adecuado para mejorar la legibilidad de la respuesta.
vlizana