Ich verwende MySQL Server 5.7.11 und diesen Satz:
updated datetime NOT NULL DEFAULT '0000-00-00 00:00:00'
ist nicht arbeiten. Fehler melden:
ERROR 1067 (42000): Invalid default value for 'updated'
Aber das Folgende:
updated datetime NOT NULL DEFAULT '1000-01-01 00:00:00'
funktioniert einfach .
Gleiches gilt für DATE.
Als sidenote wird es in mysql docs erwähnt:
Der Typ DATE wird für Werte mit einem Datumsteil, aber ohne Zeitteil verwendet. MySQL ruft DATE-Werte im Format 'JJJJ-MM-TT' ab und zeigt sie an. Der unterstützte Bereich reicht von '1000-01-01' bis '9999-12-31'.
selbst wenn sie auch sagen:
Ungültige DATE-, DATETIME- oder TIMESTAMP-Werte werden in den "Null" -Wert des entsprechenden Typs konvertiert ("0000-00-00" oder "0000-00-00 00:00:00").
Kann mir jemand mitteilen, warum dieser Fehler auftritt, wenn ich auch das zweite Zitat aus der MySQL-Dokumentation berücksichtige?
Der Fehler ist auf den SQL-Modus zurückzuführen, der gemäß der neuesten MYSQL 5.7-Dokumentation der strikte Modus sein kann
MySQL-Dokumentation 5.7 sagt :
Der strikte Modus beeinflusst, ob der Server als gültiges Datum "0000-00-00" zulässt: Wenn der strikte Modus nicht aktiviert ist, ist "0000-00-00" zulässig, und Einfügungen erzeugen keine Warnung . Wenn der strikte Modus aktiviert ist, ist "0000-00-00" nicht zulässig und Einfügungen führen zu einem Fehler, es sei denn, IGNORE wird ebenfalls angegeben. Für INSERT IGNORE und UPDATE IGNORE ist '0000-00-00' zulässig, und Einfügungen erzeugen eine Warnung.
Zum Überprüfen des MYSQL-Modus
SELECT @@GLOBAL.sql_mode global, @@SESSION.sql_mode session
STRICT_TRANS_TABLES-Modus deaktivieren
Um jedoch das Format 0000-00-00 00:00:00
zuzulassen, müssen Sie den STRICT_TRANS_TABLES-Modus in der mysql-Konfigurationsdatei oder per Befehl deaktivieren
Durch Befehl
SET sql_mode = '';
oder
SET GLOBAL sql_mode = '';
Die Verwendung des Schlüsselworts GLOBAL
erfordert Super-Präfixe und wirkt sich auf die Vorgänge aus, die alle Clients von diesem Zeitpunkt an verbinden
wenn oben nicht funktioniert, gehen Sie zu /etc/mysql/my.cnf
(laut Ubuntu) und kommentieren Sie STRICT_TRANS_TABLES
aus.
Wenn Sie den SQL-Modus beim Serverstart dauerhaft festlegen möchten, schließen Sie SET sql_mode=''
in my.cnf
unter Linux oder MacOS ein. Für Windows muss dies in der my.ini
-Datei erfolgen.
Hinweis
Der strikte Modus ist in MYSQL 5.6 jedoch standardmäßig nicht aktiviert. Daher wird der Fehler nicht laut Dokumentation zu MYSQL 6 ausgegeben
MySQL erlaubt es Ihnen, einen "Nullwert" von "0000-00-00" als "Dummy-Datum" zu speichern. Dies ist in manchen Fällen praktischer als die Verwendung von NULL-Werten und verwendet weniger Daten- und Indexspeicherplatz. Aktivieren Sie den SQL-Modus NO_ZERO_DATE, um "0000-00-00" zu verbieten.
UPDATE
In Bezug auf die Fehlersache, wie von @ Dylan-Su gesagt:
Ich glaube nicht, dass dies die Art und Weise ist, in der MYSQL im Laufe der Zeit weiterentwickelt wurde, aufgrund derer sich einige Dinge aufgrund weiterer Verbesserungen des Produkts ändern.
Ich habe jedoch einen weiteren Fehlerbericht bezüglich der Funktion NOW()
Datetime-Feld akzeptiert NOW () nicht standardmäßig
Ein weiterer nützlicher Hinweis [siehe Automatische Initialisierung und Aktualisierung für TIMESTAMP und DATETIME ]
Ab MySQL 5.6.5 können die Spalten TIMESTAMP und DATETIME automatisch initialisiert und auf das aktuelle Datum und die aktuelle Uhrzeit (d. H. Den aktuellen Zeitstempel) aktualisiert werden. Vor 5.6.5 gilt dies nur für TIMESTAMP und höchstens eine TIMESTAMP-Spalte pro Tabelle. In den folgenden Anmerkungen werden zuerst die automatische Initialisierung und Aktualisierung von MySQL 5.6.5 und höher beschrieben, und dann die Unterschiede zu den Versionen vor 5.6.5.
Update bezüglich NO_ZERO_DATE
Ab MySQL ist dieser Modus seit 5.7.4 veraltet. Für die vorherige Version müssen Sie die entsprechende Zeile in der Konfigurationsdatei auskommentieren. Siehe MySQL 5.7-Dokumentation zu NO_ZERO_DATE
Ich hatte diesen Fehler mit WAMP 3.0.6 mit MySql 5.7.14.
Lösung:
Ändern Sie Zeile 70 (falls Ihre Ini-Datei nicht betroffen ist) in c:\wamp\bin\mysql\mysql5.7.14\my.ini
-Datei aus
sql-mode= "STRICT_ALL_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_ZERO_DATE,NO_ZERO_IN_DATE,NO_AUTO_CREATE_USER"
zu
sql-mode="ERROR_FOR_DIVISION_BY_ZERO,NO_ZERO_DATE,NO_ZERO_IN_DATE,NO_AUTO_CREATE_USER"
und starten Sie alle Dienste neu.
Dadurch wird der strikte Modus deaktiviert. Gemäß der Dokumentation bedeutet "strikter Modus" einen Modus, bei dem entweder STRICT_TRANS_TABLES
oder STRICT_ALL_TABLES
aktiviert ist ..__ Die Dokumentation sagt:
"Der Standard-SQL-Modus in MySQL 5.7 enthält die folgenden Modi: ONLY_FULL_GROUP_BY, STRICT_TRANS_TABLES, NO_ZERO_IN_DATE, NO_ZERO_DATE, ERROR_FOR_DIVISION_BY_ZERO_OFFER.
Bei einigen Versionen von MYSQL (getestet 5.7. *) Unter * nix-Systemen sollten Sie folgende Syntax verwenden:
[mysqld]
sql-mode="NO_BACKSLASH_ESCAPES,STRICT_TRANS_TABLE,NO_ENGINE_SUBSTITUTION"
ohne Anführungszeichen
sql-mode=NO_ENGINE_SUBSTITUTION
Unterstrich ohne Anführungszeichen
sql_mode=NO_ENGINE_SUBSTITUTION
Unterstrich und Anführungszeichen
sql_mode="NO_ENGINE_SUBSTITUTION"
Eine umfassendere Überprüfung der Konfigurationswerte und des SQL-Modus:
Fügen Sie einfach die Zeile hinzu: sql_mode = "NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
in der Datei: /etc/mysql/mysql.conf.d/mysqld.cnf
dann Sudo service mysql restart
Ich kam in eine Situation, in der die Daten zwischen NULL und 0000-00-00 für ein Datumsfeld gemischt wurden. Aber ich wusste nicht, wie ich die '0000-00-00' auf NULL aktualisieren sollte, weil
update my_table set my_date_field=NULL where my_date_field='0000-00-00'
ist nicht mehr erlaubt . Mein Workaround war ziemlich einfach:
update my_table set my_date_field=NULL where my_date_field<'1000-01-01'
weil alle falschen my_date_field
-Werte (ob korrekte Daten oder nicht) vor diesem Datum waren.
Es funktioniert für 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)
Sie können eine SQLFiddle erstellen, um Ihr Problem neu zu erstellen.
Wenn es für MySQL 5.6 und 5.7.8 funktioniert, aber am 5.7.11 fehlschlägt. Dann ist es wahrscheinlich ein Regressionsfehler für 5.7.11.
Wählen Sie zuerst die aktuelle Sitzung aus sql_mode
:
SELECT @@SESSION.sql_mode;
Dann erhalten Sie so etwas wie Standardwert :
'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'
und dann sql_mode
ohne 'NO_ZERO_DATE'
einstellen:
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';
Wenn Sie Zuschüsse haben, können Sie dies auch für GLOBAL
tun:
SELECT @@GLOBAL.sql_mode;
SET GLOBAL sql_mode = '...';
Diese Antwort gilt nur für MySQL 5.7:
Am besten wird der sql_mode nicht wirklich leer gesetzt, stattdessen verwenden Sie in PHP eine Session-Variable mit:
SET SESSION sql_mode= 'ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'
So behalten Sie zumindest die anderen Standardwerte.
Es ist verrückt, dass die MySQL-Dokumentation nicht klar ist. Sie müssen diese Defeault-Werte in sql_mode löschen:
NO_ZERO_IN_DATE, NO_ZERO_DATE, ich verstehe, aber in den zukünftigen Versionen wird dies nicht mehr funktionieren.
STRICT_ALL_TABLES, damit werden die Parameter ignoriert, daher müssen Sie sie auch löschen.
Schließlich auch TRADITIONAL, aber die Dokumentation spricht über diesen Parameter: "Fehler statt Warnung" beim Einfügen eines falschen Werts in eine Spalte ", mit diesem Parameter werden Datumsangaben mit Nullwerten nicht eingefügt, aber ohne Ja.
MySQL ist mit diesen Parametern und Kombinationen nicht wirklich organisiert.
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';
Optionskombinationen für mysql Ver 14.14 Distrib 5.7.18, for Linux (x86_64)
.
Wirft nicht:
STRICT_TRANS_TABLES
+ NO_ZERO_DATE
Wirft:
STRICT_TRANS_TABLES
+ NO_ZERO_IN_DATE
Meine Einstellungen in /etc/mysql/my.cnf
auf Ubuntu:
[mysqld]
sql_mode = "STRICT_TRANS_TABLES,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"