it-swarm.com.de

Fehler in MySQL beim Festlegen des Standardwerts für DATE oder DATETIME

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?

76
Evhz

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

143
geeksal

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.

14
bg17aw

Konfigurationssyntaxproblem

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"

Diese funktionieren nicht:

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:

So richten Sie permanente SQL-Modus-Flags ein

4
Heroselohim

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

4

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.

2
Martin T.

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.

http://sqlfiddle.com/

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.

2
Dylan Su

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 = '...';
2
simhumileco

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.

1
stackdave
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';
0
Aris tri jaka

So lösen Sie das Problem mit MySQL Workbench (Nach dem Anwenden der Lösung auf der Serverseite):

Entfernen Sie SQL_MODE in TRADITIONAL im Einstellungsbereich.

 enter image description here

0
Vindic

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"
0
Green