Thomas Wiedmann https://twiedmann.de
• Sie befinden sich hier: Startseite > SQL-Backstube > MySQL und NOT NULL Spalten

Die SQL-Backstube

Bietet Rezepte, Lösungen und ausführliche Beispiele rund um gesundes SQL und zufriedene Datenbanken.

23.01.2011: MySQL und NOT NULL Spalten

Problemstellung

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.


Getestet mit folgender Datenbank:

* IBM DB2 9.1
* MySQL 5.1.30
* ORACLE 10g 10.2 EE


Testtabelle

Listing 1:

  1. /**
  2. * Die Tabelle
  3. */
  4. CREATE TABLE person (
  5. person_id int NOT NULL,
  6. name varchar(10) NOT NULL,
  7. gebdatum date NOT NULL,
  8. PRIMARY KEY (person_id)
  9. );

Testdaten einfügen MySQL

Listing 2:

  1. /**
  2. * Testdaten einfügen MySQL
  3. */
  4. INSERT INTO person
  5. ( person_id) VALUES
  6. ( 10);
  7. Query OK, 1 row affected, 2 warnings (0.00 sec)
  8. mysql> show warnings;
  9. +---------+------+-----------------------------------------------+
  10. | Level | Code | Message |
  11. +---------+------+-----------------------------------------------+
  12. | Warning | 1364 | Field 'name' doesn't have a default value |
  13. | Warning | 1364 | Field 'gebdatum' doesn't have a default value |
  14. +---------+------+-----------------------------------------------+
  15. 2 rows in set (0.00 sec)
  16. SELECT person_id, name, gebdatum FROM person;
  17. +-----------+------+------------+
  18. | person_id | name | gebdatum |
  19. +-----------+------+------------+
  20. | 10 | | 0000-00-00 |
  21. +-----------+------+------------+
  22. 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.


MySQL und "Default" Werte ohne DEFAULT Angabe

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.


Listing 3:

  1. SELECT person_id, name, gebdatum FROM person
  2. WHERE name IS NULL;
  3. Empty set (0.00 sec)
  4. SELECT person_id, name, gebdatum FROM person
  5. WHERE name = '';
  6. +-----------+------+------------+
  7. | person_id | name | gebdatum |
  8. +-----------+------+------------+
  9. | 10 | | 0000-00-00 |
  10. +-----------+------+------------+
  11. SELECT person_id, name, gebdatum FROM person
  12. WHERE gebdatum = '0000-00-00';
  13. +-----------+------+------------+
  14. | person_id | name | gebdatum |
  15. +-----------+------+------------+
  16. | 10 | | 0000-00-00 |
  17. +-----------+------+------------+

..und die Lösung mit SQL_MODE !!

Aber auch MySQL kennt das Standardverhalten, nur muss es noch aktiviert werden. Prüfen und setzen wir den SESSION SQL_MODE.

Listing 4:

  1. SELECT @@session.sql_mode;
  2. +--------------------+
  3. | @@session.sql_mode |
  4. +--------------------+
  5. | |
  6. +--------------------+
  7. 1 row in set (0.00 sec)
  8. SET SESSION sql_mode = 'STRICT_TRANS_TABLES';
  9. Query OK, 0 rows affected (0.00 sec)
  10. INSERT INTO person
  11. ( person_id) VALUES
  12. ( 11);
  13. ERROR 1364 (HY000): Field 'name' doesn't have a default value

Resumee

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.




Sitemap - Inhaltsverzeichnis

© 2002-2014 by Thomas Wiedmann : (Stand : 01.05.2012). 
Powered by Zend Framework and "Yahoo! User Interface" (YUI)