Recientemente me hice cargo de un antiguo proyecto creado hace 10 años. Utiliza MySQL 5.1.
Entre otras cosas, necesito cambiar el conjunto de caracteres predeterminado de latin1 a utf8.
Como ejemplo, tengo tablas como esta:
CREATE TABLE `users` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`first_name` varchar(45) CHARACTER SET latin1 COLLATE latin1_general_ci DEFAULT NULL,
`last_name` varchar(45) CHARACTER SET latin1 COLLATE latin1_general_ci DEFAULT NULL,
`username` varchar(127) CHARACTER SET latin1 COLLATE latin1_general_ci NOT NULL,
`email` varchar(127) CHARACTER SET latin1 COLLATE latin1_general_ci NOT NULL,
`pass` varchar(20) CHARACTER SET latin1 COLLATE latin1_general_ci NOT NULL,
`active` char(1) CHARACTER SET latin1 COLLATE latin1_general_ci NOT NULL DEFAULT 'Y',
`created` datetime NOT NULL,
`last_login` datetime DEFAULT NULL,
`author` varchar(1) CHARACTER SET latin1 COLLATE latin1_general_ci DEFAULT 'N',
`locked_at` datetime DEFAULT NULL,
`created_at` datetime DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
`ripple_token` varchar(36) CHARACTER SET latin1 COLLATE latin1_general_ci DEFAULT NULL,
`ripple_token_expires` datetime DEFAULT '2014-10-31 08:03:55',
`authentication_token` varchar(255) CHARACTER SET latin1 COLLATE latin1_general_ci DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `index_users_on_reset_password_token` (`reset_password_token`),
UNIQUE KEY `index_users_on_confirmation_token` (`confirmation_token`),
UNIQUE KEY `index_users_on_unlock_token` (`unlock_token`),
KEY `users_active` (`active`),
KEY `users_username` (`username`),
KEY `index_users_on_email` (`email`)
) ENGINE=InnoDB AUTO_INCREMENT=1677 DEFAULT CHARSET=utf8 CHECKSUM=1 DELAY_KEY_WRITE=1 ROW_FORMAT=DYNAMIC
Configuré mi propia Mac para trabajar en esto. Sin pensarlo demasiado, ejecuté "brew install mysql" que instaló MySQL 5.7. Entonces tengo algunos conflictos de versión.
Descargué una copia de esta base de datos y la importé.
Si intento ejecutar una consulta como esta:
ALTER TABLE users MODIFY first_name varchar(45) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL
Me sale este error:
ERROR 1292 (22007): Incorrect datetime value: '0000-00-00 00:00:00' for column 'created' at row 1
Pensé que podría solucionar esto con:
ALTER TABLE users MODIFY created datetime NULL DEFAULT '1970-01-01 00:00:00';
Query OK, 0 rows affected (0.06 sec)
Records: 0 Duplicates: 0 Warnings: 0
pero me sale:
ALTER TABLE users MODIFY first_name varchar(45) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ;
ERROR 1292 (22007): Incorrect datetime value: '0000-00-00 00:00:00' for column 'created' at row 1
¿Tengo que actualizar cada valor?
No pude hacer esto:
(en MySQL 5.7.13).
Seguí recibiendo el
Incorrect datetime value: '0000-00-00 00:00:00'
error.Curiosamente, esto funcionó:
SELECT * FROM users WHERE created = '0000-00-00 00:00:00'
. No tengo idea de por qué falla el primero y el último funciona ... ¿tal vez un error de MySQL?En cualquier caso, esta consulta ACTUALIZACIÓN funcionó:
fuente
UPDATE users SET created = NULL WHERE created = '0'
entity
DONDE createdAt = "0000-00-00 00:00:00" funciona bien, ¡pero con un error actualizado! Yo tuve el mismo problema. Solucionarlo con la solución de @obe CAST (creado como CHAR (20)) ... Creo que es un error.UPDATE users SET created = NULL WHERE created=0
(sin 'alrededor de cero)Cambiar el valor predeterminado para una columna con una
ALTER TABLE
declaración, p. Ej.... no cambia ningún valor que ya esté almacenado. El valor "predeterminado" se aplica a las filas que se insertan y para las que no se proporciona un valor para la columna.
En cuanto a por qué te encuentras con el error, es probable que la
sql_mode
configuración de tu sesión incluyaNO_ZERO_DATE
.Referencia: http://dev.mysql.com/doc/refman/5.7/en/sql-mode.html#sqlmode_no_zero_date
Cuando hizo la "importación", las instrucciones SQL que hicieron el INSERTAR en esa tabla se ejecutaron en una sesión que permitía cero fechas.
Para ver la configuración sql_mode:
-o-
En cuanto a cómo "solucionar" el problema actual, para que no se arroje el error cuando ejecute la
ALTER TABLE
instrucción.Varias opciones:
1) cambie el
sql_mode
para permitir fechas cero, eliminandoNO_ZERO_DATE
yNO_ZERO_IN_DATE
. El cambio se puede aplicar en el archivo my.cnf, por lo que después de reiniciar MySQL Server, lasql_mode
variable se inicializará en la configuración de my.cnf.Para un cambio temporal, podemos modificar la configuración con una sola sesión, sin requerir un cambio global.
2) cambie la
created
columna para permitir valores NULL y actualice las filas existentes para cambiar las fechas cero a valores nulos3) actualice las filas existentes para cambiar las fechas cero a una fecha válida
No necesitamos ejecutar declaraciones individuales para actualizar cada fila. Podemos actualizar todas las filas de una sola vez (suponiendo que sea una tabla de tamaño razonable. Para una tabla más grande, para evitar la enorme generación de deshacer / deshacer, podemos realizar la operación en trozos de tamaño razonable).
En la pregunta, el
AUTO_INCREMENT
valor que se muestra para la definición de la tabla nos asegura que el número de filas no es excesivo.Si ya hemos cambiado la
created
columna para permitirNULL
valores, podemos hacer algo como esto:O bien, podemos establecerlos en una fecha válida, por ejemplo, 2 de enero de 1970
(Tenga en cuenta que un valor de fecha y hora de la medianoche del 1 de enero de 1970 (
'1970-01-01 00:00:00'
) es una "fecha cero". Eso se evaluará como'0000-00-00 00:00:00'
fuente
sql_mode
. Las versiones más recientes de MySQL tienen configuraciones predeterminadassql_mode
que son más estrictas que las versiones anteriores. Referencia de 8,0 aquí: dev.mysql.com/doc/refman/8.0/en/sql-mode.html verNO_ZERO_DATE
,ALLOW_INVALID_DATE
et al. tenga en cuenta que algunos están incluidos en el modo ESTRICTO, por ejemploSTRICT_TRANS_TABLES
,STRICT_ALL_TABLES
y otros modos combinados. Para solucionar las restricciones, modifique temporalmente sql_mode para la sesión,Lo solucioné haciendo esto antes de la consulta
fuente
De acuerdo con el Manual de referencia de MySQL 5.7 :
Como
0000-00-00 00:00:00
no es unDATETIME
valor válido , su base de datos está rota. Es por eso que MySQL 5.7, que viene con elNO_ZERO_DATE
modo habilitado de forma predeterminada, genera un error cuando intenta realizar una operación de escritura.Puede arreglar su tabla actualizando todos los valores no válidos a cualquier otro válido, como
NULL
:Además, para evitar este problema, le recomiendo que siempre establezca la hora actual como valor predeterminado para sus
created
campos similares, de modo que se completen automáticamenteINSERT
. Solo haz:fuente
fuente
Aquí está mi solución PhpMyAdmin / Fedora 29 / MySQL 8.0 (por ejemplo):
set sql_mode='SOMETHING';
no funciona , la llamada de comando se realizó correctamente pero nada fue un cambio.set GLOBAL sql_mode='SOMETHING';
cambiar la configuración global cambio permanente.set SESSION sql_mode='SOMETHING';
cambiar la configuración de la sesión La variable SESSION afecta solo al cliente actual.https://dev.mysql.com/doc/refman/8.0/en/sql-mode.html
Entonces hago esto:
SHOW VARIABLES LIKE 'sql_mode';
ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
NO_ZERO_IN_DATE,NO_ZERO_DATE
set GLOBAL SQL_MODE='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'
Puede eliminar o agregar otro modo de la misma manera.
Esto es útil para cambiar globalmente para usar y probar marcos o sql_mode debe especificarse en cada archivo o grupo de consultas.
Adaptado de una pregunta, pregunte aquí: how-can-i-disable-mysql-strictly-mode
Ejemplo: instalar el contenido más reciente de Joomla 4.0-alpha.
Editar: en PhpMyadmin, si tiene el control del servidor, puede cambiar el
sql_mode
(y todos los demás parámetros) directamente enPlus > Variables > sql_mode
fuente
Puede cambiar el tipo de creado el campo de
datetime
avarchar(255)
, entonces se puede establecer (actualización) todos los registros que tienen el valor"0000-00-00 00:00:00"
aNULL
.Ahora, puede hacer sus consultas sin error. Una vez que haya terminado, puede modificar el tipo de campo creado para
datetime
.fuente
También tengo este error después de actualizar MySQL de 5.6 a 5.7
Descubrí que la mejor solución para mí era combinar algunas de las soluciones aquí y hacer algo que funcionara con el mínimo de entrada.
Utilizo MyPHPAdmin por la simplicidad de enviar las consultas a través de la interfaz porque entonces puedo verificar la estructura y todo eso fácilmente. Puede usar ssh directamente o alguna otra interfaz. El método debe ser similar o igual de todos modos.
...
1)
Primero revise el error real cuando intente reparar el db:
Esto me dice que la columna check_out_time en la tabla jos_menu necesita que se arreglen todas las fechas incorrectas y que se cambie el "valor predeterminado".
...
2)
Ejecuto la consulta SQL basada en la información en el mensaje de error:
Si obtiene un error, puede usar la consulta a continuación en lugar de que parezca que siempre funciona:
...
3)
Luego, una vez hecho esto, ejecuto la segunda consulta SQL:
O en el caso es una fecha que tiene que ser NULL
...
Si ejecuto la base de datos de reparación ahora obtengo:
joomla.jos_menu OK
...
Funciona bien :)
fuente
Cheque
si ve cosas de 'CERO_DATE' allí, intente
Cierre sesión y vuelva a iniciar sesión en su cliente (esto es extraño) e intente nuevamente
fuente
Hacer que el modo sql no sea estricto
si usa laravel, vaya a config-> database, vaya a la configuración de mysql y haga que el modo estricto sea falso
fuente
Tuve un problema similar pero en mi caso alguna línea tenía el valor NULL.
así que primero actualizo la tabla:
problema resuelto, al menos en mi caso.
fuente
Yo tambien tengo
información de error
Solucione esto cambiando
0000-00-00 00:00:00
a1970-01-01 08:00:00
1970-01-01 08:00:00
la marca de tiempo de unix es 0fuente
NO_ZERO_DATE
Encontré la solución en https://support.plesk.com/hc/en-us/articles/115000666509-How-to-change-the-SQL-mode-in-MySQL . Tuve esto:
Observe el
NO_ZERO_IN_DATE,NO_ZERO_DATE
en los resultados anteriores. Lo eliminé haciendo esto:Entonces tuve esto:
Después de hacer eso, podría usar con
ALTER TABLE
éxito y alterar mis tablas.fuente
Esto es lo que hice para resolver mi problema. Probé en MySQL 5.7 local ubuntu 18.04.
Antes de ejecutar esta consulta globalmente, agregué un archivo cnf en el directorio /etc/mysql/conf.d . El nombre del archivo cnf es mysql.cnf y códigos
Luego reinicio mysql
Espero que esto pueda ayudar a alguién.
fuente
NO_ENGINE_SUBSTITUTION
está en todas las columnas,SELECT @@global.sql_mode, @@session.sql_mode, @@sql_mode;
pero sigo recibiendo un error para la fecha0000-00-00 00:00:00
y hora no válida hasta que vuelva a ejecutar la primera consulta ¿set global sql_mode="NO_ENGINE_SUBSTITUTION";
Alguna idea?NO_ZERO_IN_DATE,NO_ZERO_DATE
en su versión de la línea my.ini que define elsql_mode
.Esto es increíblemente feo, pero también solucionó el problema rápidamente para mí. Su tabla necesita una clave única que usará para arreglar las columnas contaminadas. En este ejemplo, la clave primaria se llama 'id' y la columna de marca de tiempo rota se llama 'BadColumn'.
Seleccione las ID de las columnas contaminadas.
select id from table where BadColumn='0000-00-00 00:00:00'
Recopile las ID en una cadena delimitada por comas. Ejemplo:
1, 22, 33
. Utilicé un contenedor externo para esto (un script de Perl) para escupirlos rápidamente.Use su lista de ID para actualizar las columnas antiguas con una fecha válida (1971 a 2038).
update table set BadColumn='2000-01-01 00:00:00' where id in (1, 22, 33)
fuente
Mi solución
fuente
En vez de
Utilizar
fuente
Si está ingresando los datos manualmente, puede considerar eliminar los valores y los ceros en TIMESTAMP (6) .000000 para que se convierta en TIMESTAMP. Eso funcionó bien conmigo.
fuente