Bietet Rezepte, Lösungen und ausführliche Beispiele rund um gesundes SQL und zufriedene Datenbanken.
Für gewöhnlich definiert man wichtige Tabellenspalten und Pflichtfelder mit den NOT NULL Constraint, um sicherzustellen, dass die Spalte immer einen gültigen Wert enthalten muss. Bei MySQL ist dies aber nicht ausreichend, wie folgendes Beispiel zeigt.
* IBM DB2 9.1
* MySQL 5.1.30
* ORACLE 10g 10.2 EE
/**
* Die Tabelle
*/
CREATE TABLE person (
person_id int NOT NULL,
name varchar(10) NOT NULL,
gebdatum date NOT NULL,
PRIMARY KEY (person_id)
);
/**
* Testdaten einfügen MySQL
*/
INSERT INTO person
( person_id) VALUES
( 10);
Query OK, 1 row affected, 2 warnings (0.00 sec)
mysql> show warnings;
+---------+------+-----------------------------------------------+
| Level | Code | Message |
+---------+------+-----------------------------------------------+
| Warning | 1364 | Field 'name' doesn't have a default value |
| Warning | 1364 | Field 'gebdatum' doesn't have a default value |
+---------+------+-----------------------------------------------+
2 rows in set (0.00 sec)
SELECT person_id, name, gebdatum FROM person;
+-----------+------+------------+
| person_id | name | gebdatum |
+-----------+------+------------+
| 10 | | 0000-00-00 |
+-----------+------+------------+
1 row in set (0.00 sec)
Während der obige INSERT Befehl bei DB2 und ORACLE einen erwarteten Fehler "..Einfügen von NULL nicht möglich.." liefert, wird der Datensatz bei MySQL eingefügt. Zwar mit zwei Warnings, aber der Datensatz wird eingefügt.
Mit dem überraschenden Ergebnis, dass eine NOT NULL Spalte nun den den Wert NULL enthält und ein ungültiges Datum "0000-00-00" enthält? Probieren wir es einfach aus.
Unerwartete Inhalte:
1. Welchen Inhalt hat nun die Tabellenspalte NAME? NULL(?), nein sondern den Wert '' (Empty String)
2. Welchen Inhalt hat nun die Tabellenspalte GEBDATUM? Den Wert "0000-00-00", also ein ungültiges Datum.
SELECT person_id, name, gebdatum FROM person
WHERE name IS NULL;
Empty set (0.00 sec)
SELECT person_id, name, gebdatum FROM person
WHERE name = '';
+-----------+------+------------+
| person_id | name | gebdatum |
+-----------+------+------------+
| 10 | | 0000-00-00 |
+-----------+------+------------+
SELECT person_id, name, gebdatum FROM person
WHERE gebdatum = '0000-00-00';
+-----------+------+------------+
| person_id | name | gebdatum |
+-----------+------+------------+
| 10 | | 0000-00-00 |
+-----------+------+------------+
Aber auch MySQL kennt das Standardverhalten, nur muss es noch aktiviert werden. Prüfen und setzen wir den SESSION SQL_MODE.
SELECT @@session.sql_mode;
+--------------------+
| @@session.sql_mode |
+--------------------+
| |
+--------------------+
1 row in set (0.00 sec)
SET SESSION sql_mode = 'STRICT_TRANS_TABLES';
Query OK, 0 rows affected (0.00 sec)
INSERT INTO person
( person_id) VALUES
( 11);
ERROR 1364 (HY000): Field 'name' doesn't have a default value
Mit Hilfe des SQL Modes STRICT_TRANS_TABLES kann bei MySQL das übliche Verhalten für NOT NULL Spalten aktiviert werden. Nutzen Sie diese Möglichkeiten! Die damit verbesserte Datenqualität löst so manches spätere SQL-Problem gleich im Vorfeld.