Ich habe kürzlich ein altes Projekt übernommen, das vor 10 Jahren erstellt wurde. Es verwendet MySQL 5.1.
Unter anderem muss ich den Standardzeichensatz von latin1 in utf8 ändern.
Als Beispiel habe ich Tabellen wie diese:
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
Ich habe meinen eigenen Mac eingerichtet, um daran zu arbeiten. Ohne zu viel darüber nachzudenken, habe ich "Brew Install MySQL" ausgeführt, das MySQL 5.7 installiert hat. Ich habe also einige Versionskonflikte.
Ich habe eine Kopie dieser Datenbank heruntergeladen und importiert.
Wenn ich versuche, eine Abfrage wie folgt auszuführen:
ALTER TABLE users MODIFY first_name varchar(45) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL
Ich erhalte diesen Fehler:
ERROR 1292 (22007): Incorrect datetime value: '0000-00-00 00:00:00' for column 'created' at row 1
Ich dachte, ich könnte das beheben mit:
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
aber ich bekomme:
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
Muss ich jeden Wert aktualisieren?
Ich konnte das nicht tun:
(unter MySQL 5.7.13).
Ich bekam immer wieder den
Incorrect datetime value: '0000-00-00 00:00:00'
Fehler.Seltsamerweise funktionierte das :
SELECT * FROM users WHERE created = '0000-00-00 00:00:00'
. Ich habe keine Ahnung, warum Ersteres fehlschlägt und Letzteres funktioniert ... vielleicht ein MySQL-Fehler?In jedem Fall funktionierte diese UPDATE-Abfrage:
quelle
UPDATE users SET created = NULL WHERE created = '0'
entity
WHERE createdAt = "0000-00-00 00:00:00" funktioniert einwandfrei, aber mit einem aktualisierten Fehler! Ich hatte das gleiche Problem. Beheben Sie es mit der Lösung von @obe CAST (erstellt als CHAR (20)) ... Ich denke, dass es ein Fehler ist.UPDATE users SET created = NULL WHERE created=0
(ohne 'um Null)Ändern des Standardwerts für eine Spalte mit einer
ALTER TABLE
Anweisung, z... ändert keine bereits gespeicherten Werte. Der "Standard" -Wert gilt für Zeilen, die eingefügt werden und für die kein Wert für die Spalte angegeben wird.
Es ist wahrscheinlich, dass die
sql_mode
Einstellung für Ihre Sitzung enthält , warum der Fehler auftrittNO_ZERO_DATE
.Referenz: http://dev.mysql.com/doc/refman/5.7/en/sql-mode.html#sqlmode_no_zero_date
Beim "Importieren" wurden die SQL-Anweisungen, mit denen INSERT in diese Tabelle ausgeführt wurde, in einer Sitzung ausgeführt, in der keine Daten zulässig waren.
So zeigen Sie die Einstellung sql_mode an:
-oder-
Was das "Beheben" des aktuellen Problems angeht, damit der Fehler beim Ausführen der
ALTER TABLE
Anweisung nicht ausgelöst wird .Mehrere Möglichkeiten:
1) Ändern Sie das
sql_mode
, um Nulldaten zuzulassen, indem SieNO_ZERO_DATE
und entfernenNO_ZERO_IN_DATE
. Die Änderung kann in der Datei my.cnf angewendet werden. Nach einem Neustart von MySQL Server wird diesql_mode
Variable auf die Einstellung in my.cnf initialisiert.Bei einer vorübergehenden Änderung können wir die Einstellung mit einer einzigen Sitzung ändern, ohne dass eine globale Änderung erforderlich ist.
2) Ändern Sie die
created
Spalte, um NULL-Werte zuzulassen, und aktualisieren Sie die vorhandenen Zeilen, um die Nulldaten in Nullwerte zu ändern3) Aktualisieren Sie die vorhandenen Zeilen, um die Nulldaten in ein gültiges Datum zu ändern
Wir müssen keine einzelnen Anweisungen ausführen, um jede Zeile zu aktualisieren. Wir können alle Zeilen auf einen Schlag aktualisieren (vorausgesetzt, es handelt sich um eine Tabelle mit angemessener Größe. Bei einer größeren Tabelle können wir den Vorgang in Abschnitten mit angemessener Größe ausführen, um ein starkes Zurückrollen / Rückgängigmachen zu vermeiden.)
In der Frage stellt der
AUTO_INCREMENT
für die Tabellendefinition angezeigte Wert sicher, dass die Anzahl der Zeilen nicht zu hoch ist.Wenn wir die
created
Spalte bereits geändert haben , umNULL
Werte zu berücksichtigen, können wir Folgendes tun:Oder wir können diese auf ein gültiges Datum setzen, z. B. den 2. Januar 1970
(Beachten Sie, dass ein Datetime - Wert von Mitternacht 1. Januar 1970 (
'1970-01-01 00:00:00'
) ist eine „Null - date“. Das ausgewertet wird zu sein'0000-00-00 00:00:00'
quelle
sql_mode
. Neuere Versionen von MySQL haben Standardeinstellungensql_mode
, die strenger sind als frühere Versionen. Referenz für 8.0 hier: dev.mysql.com/doc/refman/8.0/en/sql-mode.html sieheNO_ZERO_DATE
,ALLOW_INVALID_DATE
et al. beachten Sie, dass einige im Strict - Modus zum Beispiel enthalten sindSTRICT_TRANS_TABLES
,STRICT_ALL_TABLES
und andere Combo - Modi. Um die Einschränkungen zu umgehen, ändern Sie vorübergehend sql_mode für die Sitzung.Ich habe es dadurch vor der Abfrage behoben
quelle
Gemäß MySQL 5.7 Referenzhandbuch :
Da dies
0000-00-00 00:00:00
kein gültigerDATETIME
Wert ist, ist Ihre Datenbank fehlerhaft. Aus diesem Grund gibt MySQL 5.7 - dasNO_ZERO_DATE
standardmäßig mit aktiviertem Modus geliefert wird - einen Fehler aus, wenn Sie versuchen, einen Schreibvorgang auszuführen.Sie können Ihre Tabelle zu aktualisieren alle ungültigen Werte auf andere gültige beheben, wie
NULL
:Um dieses Problem zu vermeiden, empfehle ich Ihnen, immer die aktuelle Zeit als Standardwert für Ihre
created
ähnlichen Felder festzulegen, damit diese automatisch ausgefüllt werdenINSERT
. Mach einfach:quelle
quelle
Hier ist meine Lösung PhpMyAdmin / Fedora 29 / MySQL 8.0 (zum Beispiel):
set sql_mode='SOMETHING';
funktioniert nicht , Befehlsaufruf erfolgreich, aber nichts wurde geändert.set GLOBAL sql_mode='SOMETHING';
globale Konfiguration ändern permanente Änderung.set SESSION sql_mode='SOMETHING';
Sitzungskonfiguration ändern Die Variable SESSION wirkt sich nur auf den aktuellen Client aus.https://dev.mysql.com/doc/refman/8.0/en/sql-mode.html
Also mache ich das:
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'
Sie können auf die gleiche Weise andere Modi entfernen oder hinzufügen.
Dies ist hilfreich, um global zu ändern und Frameworks zu verwenden, oder sql_mode muss in jeder Datei oder einer Reihe von Abfragen angegeben werden.
Angepasst an eine Frage stellen Sie hier: Wie kann ich den MySQL-Strict-Modus deaktivieren?
Beispiel: Installieren Sie den neuesten Joomla 4.0-Alpha-Inhalt.
Bearbeiten: Wenn Sie in PhpMyadmin die Kontrolle über den Server haben, können Sie die
sql_mode
(und alle anderen Parameter) direkt in ändernPlus > Variables > sql_mode
quelle
Sie können den Typ des erstellten Felds von
datetime
bis ändernvarchar(255)
und dann alle Datensätze mit dem Wert"0000-00-00 00:00:00"
bis festlegen (aktualisieren)NULL
.Jetzt können Sie Ihre Abfragen fehlerfrei ausführen. Nachdem Sie fertig sind , können Sie die Art des Feldes verändern geschaffen zu
datetime
.quelle
Ich habe diesen Fehler auch nach dem Upgrade von MySQL von 5.6 auf 5.7
Ich fand heraus, dass die beste Lösung für mich darin bestand, einige der Lösungen hier zu kombinieren und etwas daraus zu machen, das mit minimalem Aufwand funktioniert.
Ich benutze MyPHPAdmin, um die Anfragen einfach über die Schnittstelle zu senden, da ich dann die Struktur und das alles leicht überprüfen kann. Sie können ssh direkt oder eine andere Schnittstelle verwenden. Die Methode sollte sowieso ähnlich oder gleich sein.
...
1.
Überprüfen Sie zuerst den tatsächlichen Fehler, wenn Sie versuchen, die Datenbank zu reparieren:
Dies sagt mir, dass in der Spalte checked_out_time in der Tabelle jos_menu alle fehlerhaften Daten behoben und der "Standard" geändert werden muss.
...
2.
Ich führe die SQL-Abfrage basierend auf den Informationen in der Fehlermeldung aus:
Wenn Sie eine Fehlermeldung erhalten, können Sie stattdessen die folgende Abfrage verwenden, die anscheinend immer funktioniert:
...
3.
Sobald dies erledigt ist, führe ich die zweite SQL-Abfrage aus:
Oder in dem Fall ist es ein Datum, das NULL sein muss
...
Wenn ich jetzt die Reparaturdatenbank starte, bekomme ich:
joomla.jos_menu OK
...
Funktioniert gut :)
quelle
Prüfen
Wenn Sie dort 'ZERO_DATE' sehen, versuchen Sie es
Melden Sie sich bei Ihrem Client ab und wieder an (das ist seltsam) und versuchen Sie es erneut
quelle
Machen Sie den SQL-Modus nicht streng
Wenn Sie Laravel verwenden, gehen Sie zu config-> database, gehen Sie zu mysql settings und machen Sie den strengen Modus false
quelle
Ich hatte ein ähnliches Problem, aber in meinem Fall hatte eine Zeile den Wert NULL.
Also aktualisiere ich zuerst die Tabelle:
Problem gelöst, zumindest in meinem Fall.
quelle
Ich habe auch
Fehlerinfo
Dieses Problem beheben , indem Sie
0000-00-00 00:00:00
auf1970-01-01 08:00:00
1970-01-01 08:00:00
Unix-Zeitstempel ist 0quelle
NO_ZERO_DATE
Ich fand die Lösung unter https://support.plesk.com/hc/en-us/articles/115000666509-How-to-change-the-SQL-mode-in-MySQL . Ich hatte das:
Beachten Sie die
NO_ZERO_IN_DATE,NO_ZERO_DATE
in den Ergebnissen oben. Ich habe das dadurch entfernt:Dann hatte ich folgendes:
Danach konnte ich
ALTER TABLE
meine Tabellen erfolgreich verwenden und ändern.quelle
Dies ist, was ich getan habe, um mein Problem zu lösen. Ich habe in lokalem MySQL 5.7 Ubuntu 18.04 getestet .
Bevor ich diese Abfrage global ausführte, fügte ich eine cnf-Datei im Verzeichnis /etc/mysql/conf.d hinzu . Der cnf-Dateiname lautet mysql.cnf und Codes
Dann starte ich MySQL neu
Hoffe das kann jemandem helfen.
quelle
NO_ENGINE_SUBSTITUTION
in allen Spalten von,SELECT @@global.sql_mode, @@session.sql_mode, @@sql_mode;
aber ich erhalte immer noch einen Fehler für die ungültige Datums- / Uhrzeitangabe,0000-00-00 00:00:00
bis ich die erste Abfrage erneut ausführe.set global sql_mode="NO_ENGINE_SUBSTITUTION";
Irgendwelche Ideen?NO_ZERO_IN_DATE,NO_ZERO_DATE
in Ihrer Version die Zeile my.ini zu entfernen, die das definiertsql_mode
.Das ist unglaublich hässlich, aber es hat das Problem auch schnell für mich behoben. Ihre Tabelle benötigt einen eindeutigen Schlüssel, mit dem Sie die verschmutzten Spalten reparieren können. In diesem Beispiel heißt der Primärschlüssel 'id' und die unterbrochene Zeitstempelspalte 'BadColumn'.
Wählen Sie die IDs der verschmutzten Spalten aus.
select id from table where BadColumn='0000-00-00 00:00:00'
Sammeln Sie die IDs in einer durch Kommas getrennten Zeichenfolge. Beispiel :
1, 22, 33
. Ich habe dafür einen externen Wrapper verwendet (ein Perl-Skript), um sie alle schnell auszuspucken.Verwenden Sie Ihre ID-Liste, um die alten Spalten mit einem gültigen Datum (1971 bis 2038) zu aktualisieren.
update table set BadColumn='2000-01-01 00:00:00' where id in (1, 22, 33)
quelle
Meine Lösung
quelle
Anstatt
Verwenden
quelle
Wenn Sie die Daten manuell eingeben, können Sie die Werte und Nullen im TIMESTAMP (6) .000000 entfernen, damit sie zum TIMESTAMP werden. Das hat bei mir gut funktioniert.
quelle