MySQL Falscher Datums- / Uhrzeitwert: '0000-00-00 00:00:00'

155

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?

Lorm
quelle

Antworten:

12

Mein Vorschlag, wenn die Tabelle leer oder nicht sehr groß ist, besteht darin, die create-Anweisungen als SQL-Datei zu exportieren und sie nach Ihren Wünschen neu zu schreiben. Machen Sie dasselbe auch, wenn Sie über vorhandene Daten verfügen, z. B. export insert-Anweisungen (ich empfehle, dies in einer separaten Datei als create-Anweisungen zu tun). Lassen Sie zum Schluss die Tabelle fallen und führen Sie zuerst die Anweisung create aus und fügen Sie sie dann ein.

Sie können für diesen mysqldumpBefehl entweder einen Befehl verwenden, der in Ihrer MySQL-Installation enthalten ist, oder Sie können auch MySQL Workbench installieren, ein kostenloses grafisches Tool, das auch diese Option auf sehr anpassbare Weise enthält, ohne nach bestimmten Befehlsoptionen suchen zu müssen.

Lucia Pasarin
quelle
Lucia Pasarin, ich mag Ihre Idee sehr, aber werden die Daten nicht abgeschnitten? Nehmen einige UTF8-Daten mehr Bytes ein als latin1? Wenn etwas früher in varchar 255 passte, wird es jetzt vielleicht nicht? Sollte ich vielleicht alle Varchare in "Text" -Felder ändern?
Lorm
Ja, du hast recht. Dies kann passieren, da latin1 1 Byte pro Zeichen verwendet, während utf8 höchstens 4 Byte pro Zeichen verwendet (abhängig von der Version von MySQL und dem Typ von utf8 dev.mysql.com/doc/refman/5.5/en/charset-unicode -utf8.html ). Daher benötigen Sie nicht unbedingt den Typ TEXT. Ich würde davon ausgehen, dass x4 Ihre zuvor vorhandenen Größen funktionieren sollten.
Lucia Pasarin
Dies ist das Datenbankäquivalent zur Neuformatierung Ihrer Festplatte, wenn Sie eine Datei löschen möchten. Man kann mit Sicherheit sagen, dass diese Lösung in einer Produktionsumgebung nicht akzeptabel ist.
Brandon
198

Ich konnte das nicht tun:

UPDATE users SET created = NULL WHERE created = '0000-00-00 00:00:00'

(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:

UPDATE users SET created = NULL WHERE CAST(created AS CHAR(20)) = '0000-00-00 00:00:00'
gehorche
quelle
13
Ich hatte das gleiche Problem, aber das Setzen des letzten Teils auf nur 0 hat es für mich wie UPDATE users SET created = NULL WHERE created = '0'
folgt
SELECT * FROM entityWHERE 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.
Chrysweel
44
Für mich funktionierte es wie UPDATE users SET created = NULL WHERE created=0(ohne 'um Null)
KIR
1
Um ein "0000-00-00" -Datum nur ohne Zeitstempel zu ersetzen, habe ich CHAR (11)
D.Tate
1
Das ist reines Genie. Warum ist dies nicht die akzeptierte Antwort? Für Datum nur ohne Zeitstempel ist der Mindestwert 1000-01-01. Verwenden Sie dies als Standardwert für jedes Datumsattribut, das Sie leer lassen möchten, oder mit dem Wert 0000-00-00.
Arvanitis Christos
155

Ändern des Standardwerts für eine Spalte mit einer ALTER TABLEAnweisung, z

 ALTER TABLE users MODIFY created datetime  NULL DEFAULT '1970-01-02'

... ä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_modeEinstellung für Ihre Sitzung enthält , warum der Fehler auftritt NO_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:

SHOW VARIABLES LIKE 'sql_mode' ;

-oder-

SELECT @@sql_mode ;

Was das "Beheben" des aktuellen Problems angeht, damit der Fehler beim Ausführen der ALTER TABLEAnweisung nicht ausgelöst wird .

Mehrere Möglichkeiten:

1) Ändern Sie das sql_mode, um Nulldaten zuzulassen, indem Sie NO_ZERO_DATEund entfernen NO_ZERO_IN_DATE. Die Änderung kann in der Datei my.cnf angewendet werden. Nach einem Neustart von MySQL Server wird die sql_modeVariable 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.

-- save current setting of sql_mode
SET @old_sql_mode := @@sql_mode ;

-- derive a new value by removing NO_ZERO_DATE and NO_ZERO_IN_DATE
SET @new_sql_mode := @old_sql_mode ;
SET @new_sql_mode := TRIM(BOTH ',' FROM REPLACE(CONCAT(',',@new_sql_mode,','),',NO_ZERO_DATE,'  ,','));
SET @new_sql_mode := TRIM(BOTH ',' FROM REPLACE(CONCAT(',',@new_sql_mode,','),',NO_ZERO_IN_DATE,',','));
SET @@sql_mode := @new_sql_mode ;

-- perform the operation that errors due to "zero dates"

-- when we are done with required operations, we can revert back
-- to the original sql_mode setting, from the value we saved
SET @@sql_mode := @old_sql_mode ;

2) Ändern Sie die createdSpalte, um NULL-Werte zuzulassen, und aktualisieren Sie die vorhandenen Zeilen, um die Nulldaten in Nullwerte zu ändern

3) 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_INCREMENTfür die Tabellendefinition angezeigte Wert sicher, dass die Anzahl der Zeilen nicht zu hoch ist.

Wenn wir die createdSpalte bereits geändert haben , um NULLWerte zu berücksichtigen, können wir Folgendes tun:

UPDATE  `users` SET `created` = NULL WHERE `created` = '0000-00-00 00:00:00'

Oder wir können diese auf ein gültiges Datum setzen, z. B. den 2. Januar 1970

UPDATE  `users` SET `created` = '1970-01-02' WHERE `created` = '0000-00-00 00:00:00'

(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'

spencer7593
quelle
3
Ja, das hat bei mir funktioniert. Ich habe in der Datei my.ini nach dem SQL-Modus gesucht und NO_ZERO_IN_DATE und NO_ZERO_DATE entfernt. dann den Dienst neu gestartet. danke spencer7593!
Mili
Setzen Sie NO_ZERO_DATE: stackoverflow.com/questions/3891896/…
Benutzer 1007017
Wenn ich # 2 "die erstellte Spalte so ändern, dass NULL-Werte zulässig sind", kann ich dies nicht tun, da die Spaltenwerte immer noch den Fehler erzeugen. Ganz festgefahren.
Mike Weir
1
@MikeWeir: Vermutlich bedeutet " lässt mich nicht ", dass ein Fehler zurückgegeben wird, wenn eine SQL-Anweisung ausgeführt wird. Das liegt wahrscheinlich an der Einstellung von sql_mode. Neuere Versionen von MySQL haben Standardeinstellungen sql_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 siehe NO_ZERO_DATE, ALLOW_INVALID_DATEet al. beachten Sie, dass einige im Strict - Modus zum Beispiel enthalten sind STRICT_TRANS_TABLES, STRICT_ALL_TABLESund andere Combo - Modi. Um die Einschränkungen zu umgehen, ändern Sie vorübergehend sql_mode für die Sitzung.
spencer7593
@ spencer7593 sicher. Ich hatte auch nicht das Gefühl, dass diese Option die beste war. Ich habe Ihren Rat befolgt, einen sehr alten Datumswert (1970) festzulegen, und mein System wird ihn einfach ignorieren. Vielen Dank für all Ihre Details.
Mike Weir
67

Ich habe es dadurch vor der Abfrage behoben

SET SQL_MODE='ALLOW_INVALID_DATES';
Tariq Khan
quelle
Dies ist die einzige Antwort. Verwendet als: --init-command = 'SET SESSION FOREIGN_KEY_CHECKS = 0; SET SQL_MODE =' ALLOW_INVALID_DATES '
Konchog
Ich danke dir sehr. Ich kann nicht erklären, was für ein Schmerz dieses Problem für mich war.
Dieter Gribnitz
42

Gemäß MySQL 5.7 Referenzhandbuch :

Der Standard-SQL-Modus in MySQL 5.7 umfasst die folgenden Modi: ONLY_FULL_GROUP_BY, STRICT_TRANS_TABLES, NO_ZERO_IN_DATE, NO_ZERO_DATE, ERROR_FOR_DIVISION_BY_ZERO, NO_AUTO_CREATE_USER und NO_ENGINE.

Da dies 0000-00-00 00:00:00kein gültiger DATETIMEWert ist, ist Ihre Datenbank fehlerhaft. Aus diesem Grund gibt MySQL 5.7 - das NO_ZERO_DATEstandardmäß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:

UPDATE users SET created = NULL WHERE created < '0000-01-01 00:00:00'

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 werden INSERT. Mach einfach:

ALTER TABLE users
ALTER created SET DEFAULT CURRENT_TIMESTAMP
Ivan Filho
quelle
8
SET sql_mode = 'NO_ZERO_DATE';
UPDATE `news` SET `d_stop`='2038-01-01 00:00:00' WHERE `d_stop`='0000-00-00 00:00:00'
Andrew March
quelle
4
Diese Antwort würde durch die Diskussion verbessert, warum dies das Problem löst.
KevinO
wirkt sich dies auf den datetime-Speicher aus? oder Probleme verursachen
Fragen Sie Bytes
8

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:

  • Holen Sie sich SQL_MODE: SHOW VARIABLES LIKE 'sql_mode';
  • Ergebnis: ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
  • Entfernen Sie auf dem Ergebnis: NO_ZERO_IN_DATE,NO_ZERO_DATE
  • Neue Konfiguration festlegen: 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

Shim-Sao
quelle
5

Sie können den Typ des erstellten Felds von datetimebis ändern varchar(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.

Abdallah Ajlouni
quelle
4

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:

joomla.jos_menu Hinweis: Die Spalten TIME / TIMESTAMP / DATETIME im alten Format wurden auf das neue Format aktualisiert.

Warnung: Falscher Datums- / Uhrzeitwert: '0000-00-00 00:00:00' für die Spalte 'checked_out_time' in Zeile 1

Fehler: Ungültiger Standardwert für 'checked_out_time'

Status: Operation fehlgeschlagen

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:

UPDATE jos_menu SET checked_out_time = '1970-01-01 08:00:00' WHERE checked_out_time = 0

Wenn Sie eine Fehlermeldung erhalten, können Sie stattdessen die folgende Abfrage verwenden, die anscheinend immer funktioniert:

UPDATE jos_menu SET checked_out_time = '1970-01-01 08:00:00' WHERE CAST(checked_out_time AS CHAR(20)) = '0000-00-00 00:00:00'

...

3.

Sobald dies erledigt ist, führe ich die zweite SQL-Abfrage aus:

ALTER TABLE `jos_menu` CHANGE `checked_out_time` `checked_out_time` DATETIME NULL DEFAULT CURRENT_TIMESTAMP;

Oder in dem Fall ist es ein Datum, das NULL sein muss

ALTER TABLE `jos_menu` CHANGE `checked_out_time` `checked_out_time` DATETIME NULL DEFAULT NULL;

...

Wenn ich jetzt die Reparaturdatenbank starte, bekomme ich:

joomla.jos_menu OK

...

Funktioniert gut :)

Don King
quelle
4

Prüfen

SELECT @@sql_mode;

Wenn Sie dort 'ZERO_DATE' sehen, versuchen Sie es

SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode,'NO_ZERO_DATE',''));   
SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode,'NO_ZERO_IN_DATE',''));   

Melden Sie sich bei Ihrem Client ab und wieder an (das ist seltsam) und versuchen Sie es erneut

Commonpike
quelle
3

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

Milind Chaudhary
quelle
Kann ich das in myphpadmin machen?
Don King
phpMyAdmin ist nur eine Schnittstelle zur Verwendung des eigentlichen MySQL-Servers. Es spielt keine Rolle, welche Schnittstelle Sie verwenden. MySQL-Befehle ändern sich nicht mit der Schnittstelle. Versuchen Sie diesen Befehl (set sql_mode = '';) oder diesen (set global sql_mode = '';), um ihn auszuschalten.
Milind Chaudhary
1
Ja, ich fand alles, was benötigt wird, um den strengen Modus auszuschalten, das Hinzufügen von sql_mode = (und nichts danach) am Ende von my.cnf
Don King
3

Ich hatte ein ähnliches Problem, aber in meinem Fall hatte eine Zeile den Wert NULL.

Also aktualisiere ich zuerst die Tabelle:

update `my_table`set modified = '1000-01-01 00:00:00' WHERE modified is null

Problem gelöst, zumindest in meinem Fall.

Lenon Tolfo
quelle
2

Ich habe auch

SQLSTATE [22007]: Ungültiges Datum / Uhrzeit-Format: 1292 Falscher Datum / Uhrzeit-Wert: '0000-00-00 00:00:00' für Spalte

Fehlerinfo

Dieses Problem beheben , indem Sie 0000-00-00 00:00:00 auf 1970-01-01 08:00:00

1970-01-01 08:00:00 Unix-Zeitstempel ist 0

Tekintian
quelle
1
Das Problem ist, dass OP das Datum aufgrund eines Fehlers nicht ändern kann. Ich denke, es ist ein Fehler vonNO_ZERO_DATE
GusDeCooL
2

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:

mysql> show variables like 'sql_mode';
+---------------+-------------------------------------------------------------------------------------------------------------------------------------------+
| Variable_name | Value                                                                                                                                     |
+---------------+-------------------------------------------------------------------------------------------------------------------------------------------+
| sql_mode      | 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 |
+---------------+-------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set, 1 warning (0.01 sec)

Beachten Sie die NO_ZERO_IN_DATE,NO_ZERO_DATEin den Ergebnissen oben. Ich habe das dadurch entfernt:

mysql> SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';
Query OK, 0 rows affected, 1 warning (0.00 sec)

Dann hatte ich folgendes:

mysql> show variables like 'sql_mode';
+---------------+--------------------------------------------------------------------------------------------------------------+
| Variable_name | Value                                                                                                        |
+---------------+--------------------------------------------------------------------------------------------------------------+
| sql_mode      | ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |
+---------------+--------------------------------------------------------------------------------------------------------------+
1 row in set, 1 warning (0.01 sec)

Danach konnte ich ALTER TABLEmeine Tabellen erfolgreich verwenden und ändern.

Jaime Montoya
quelle
1

Dies ist, was ich getan habe, um mein Problem zu lösen. Ich habe in lokalem MySQL 5.7 Ubuntu 18.04 getestet .

set global sql_mode="NO_ENGINE_SUBSTITUTION";

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

[mysqld]
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ALLOW_INVALID_DATES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

Dann starte ich MySQL neu

sudo service mysql restart

Hoffe das kann jemandem helfen.

Kalyan Halder Raaz
quelle
Diese Lösung funktioniert, bis ich den MySQL-Server neu starte. Auch nach dem Neustart steht der Wert NO_ENGINE_SUBSTITUTIONin 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:00bis ich die erste Abfrage erneut ausführe. set global sql_mode="NO_ENGINE_SUBSTITUTION";Irgendwelche Ideen?
Smamatti
Die Lösung in meinem Fall bestand darin, NO_ZERO_IN_DATE,NO_ZERO_DATEin Ihrer Version die Zeile my.ini zu entfernen, die das definiert sql_mode.
Smamatti
1

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

  1. Wählen Sie die IDs der verschmutzten Spalten aus.

    select id from table where BadColumn='0000-00-00 00:00:00'

  2. 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.

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

felwithe
quelle
1

Meine Lösung

SET sql_mode='';
UPDATE tnx_k2_items
SET created_by = 790
, modified = '0000-00-00 00:00:00'
, modified_by = 0
VietPublic
quelle
1

Anstatt

UPDATE your_table SET your_column = new_valid_value where your_column = '0000-00-00 00:00:00';

Verwenden

UPDATE your_table SET your_column = new_valid_value where your_column = 0;
R2D3
quelle
0

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.

Isaac
quelle