MySQL Strict Mode
Was ist der Strict Mode?
Der in MySQL 8 aktive "Strict Mode" lehnt Datenbank-Abfragen mit ungültigen Daten ab. Bei Scripten, welche ungültige Daten in die Datenbank schreiben, wird nun eine Fehlermeldung angezeigt anstatt dass ungültige Daten in die Datenbank geschrieben werden. Das Datenbank-Schema oder die Queries, welche das Script ausführt, müssen entweder korrigiert werden oder der Strict Mode muss für die Verbindungen des Scripts abgeschaltet werden.
In MySQL 8 ist standardmäßig der "Strict Mode" aktiv, welcher INSERT- und UPDATE-Queries mit ungültigen Daten ablehnt. Scripte, welche ungültige Daten in die Datenbank schreiben funktionieren mit dem Strict Mode nicht. Die Scripts sind durch das Aktivieren des Strict Mode nicht "kaputt gegangen", sondern waren schon immer fehlerhaft. MySQL hat bisher nach dem fehlerhaften Query Warnungen zurückgegeben, welche höchstwahrscheinlich nicht abgefragt bzw. beachtet wurden. Um das Problem zu lösen müssen entweder das Datenbank-Schema oder die Queries, welche das Script ausführt, korrigiert werden oder der Strict Mode muss für die Verbindungen des Scripts abgeschaltet werden.
Typische Fehlerfälle
Der Strict Mode verhindert, dass Queries ausgeführt werden, welche zu Datenverlust oder Fehlern bei der Daten-Integrität führen. Es handelt sich also um einen Unterschied zwischen den Daten, welche die Datenbank speichern soll bzw. darf und den Daten, welche das Script versucht, in die Datenbank einzufügen.
Die folgenden Fälle sind Beispiele, welche MySQL mit deaktiviertem Strict Mode speichert und nur eine Warnung zurückgibt, wohingegen mit aktiviertem Strict Mode ein Fehler zurückgegeben wird und die Daten (korrekterweise!) nicht gespeichert werden.
Zu kurze VARCHAR-Felder: ein klassisches Beispiel sind Scripts, welche IP-Adressen speichern, wobei die Script-Entwickler IPv6 vergessen haben. Die Feld-Längen sind dann typischerweise 15 Zeichen lang (für IPv4-Adressen in Form von xxx.xxx.xxx.xxx). IPv6-Adressen können deutlich länger sein. Wird eine IPv6-Adresse eingefügt müsste MySQL diese zusätzlichen Zeichen abschneiden. Mit deaktiviertem Strict Mode schneidet MySQL alle Zeichen nach dem 15. Zeichen ab, mit aktiviertem Strict Mode wird ein Fehler zurückgegeben. In diesem Fall wird im Regelfall die Länge des Felds angepasst, um das Problem zu beheben.
Ungültige Zeit- oder Datums-Werte: Welche Datumswerte abgewiesen werden, hängt von den aktiven SQL-Modi ab. Für das Null-Datum 0000-00-00 ist insbesondere das Zusammenspiel von Strict Mode und NO_ZERO_DATE maßgeblich. Speichere ein gültiges Datum oder, wenn fachlich passend und im Schema erlaubt, NULL.
Feld ohne erlaubtes NULL und ohne Default-Wert: Wird eine erforderliche Spalte beim INSERT ausgelassen und hat sie keinen Standardwert, kann Strict Mode die Abfrage ablehnen. Ein ausgelassener Wert ist nicht dasselbe wie ein ausdrücklich übergebenes NULL. Passe die Eingaben oder einen fachlich passenden Standardwert beziehungsweise die NULL-Zulässigkeit im Schema an.
Lösungen
Scripts und ggf. ihre Datenbank-Schemata (=Tabellen-Definitionen), die mit Strict Mode nicht funktionieren, müssen entweder angepasst werden oder der Strict Mode wird abgeschaltet. Natürlich ist es generell sinnvoll, das zugrunde liegende Problem zu lösen, das ist aber nicht immer möglich (keine entsprechenden Kenntnisse und kein Zugang zu den Entwicklern der Scripte). In einigen Fall ist daher das Abschalten des Strict Mode eine Lösung, auch wenn weiterhin ungültige Daten gespeichert werden.
Korrigieren der ungültigen Datenbank-Queries
Untersuche zuerst die Fehlermeldung der abgewiesenen Abfrage. Wenn Du das Verhalten ohne Strict Mode nachvollziehen musst, nutze eine Testdatenbank mit gesicherten Beispieldaten und passe nur die betreffenden Modi vorübergehend an (siehe nächster Abschnitt). Zusätzlich wird das Script so angepasst, dass nach jedem MySQL-Query ein weiterer Query "SHOW WARNINGS" ausgeführt wird. Dieser Query gibt dann die Warnungen (=die Fehlermeldung des Strict Mode) zurück. Anschließend können die Fehler behoben werden. Teilweise ist es nötig, das Datenbank-Schema zu ändern (z.B. die Länge von VARCHAR-Feldern zu vergrößern, NULL für ein Feld zu erlauben oder einen Default-Wert für ein Feld hinzuzufügen), in anderen Fällen muss das Script angepasst werden.
Abschalten des Strict Mode
Der SQL-Modus lässt sich für die jeweilige Datenbankverbindung setzen. Prüfe zunächst die aktiven Modi:
SELECT @@SESSION.sql_mode;
Entferne bei einer notwendigen vorübergehenden Ausnahme nur STRICT_TRANS_TABLES und STRICT_ALL_TABLES aus dieser Liste und setze die übrigen Modi mit SET SESSION sql_mode = 'VERBLEIBENDE_MODI';. VERBLEIBENDE_MODI ist ein Platzhalter für Deine tatsächlich ermittelte Liste. Die Änderung gilt nur bis zum Verbindungsende oder einer erneuten Änderung. SET sql_mode = ''; entfernt dagegen alle Modi, darunter ONLY_FULL_GROUP_BY und weitere Prüfungen; verwende dies nicht als pauschale Strict-Mode-Reparatur.
Typischerweise ist die korrekte Stelle dafür direkt nach dem mysqli_connect bzw. $db->connect im Datenbank-Konnektor.