Thomas Wiedmann https://twiedmann.de
• Sie befinden sich hier: Startseite > SQL-Backstube > DEFAULT Werte und Datenbank TRIGGER

Die SQL-Backstube

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

28.11.2010: DEFAULT Werte und Datenbank TRIGGER

Problemstellung

Tabellen enthalten häufig Pflichtfelder, die ausgefüllt werden müssen, sowie optionale Spalten, die mal bekannt sind und mal nicht. Für diese optionalen Spalten werden häufig DEFAULT Werte im CREATE TABLE Kommando festgelegt. Soweit so klar, scheint es jedenfalls. Was passiert nun, wenn die optionalen Spalten einen NULL Wert zugewiesen bekommen? Aber beginnen wir das Szenario wieder mit einem schönen Beispiel.


Getestet mit folgender Datenbank:

* MySQL 5.1.30


Testtabelle

Listing 1:

  1. /**
  2. * Adresstabelle mit DEFAULT Constraint
  3. */
  4. CREATE TABLE adresse (
  5. id INT NOT NULL,
  6. vorname VARCHAR(50) NOT NULL,
  7. name VARCHAR(50) NOT NULL,
  8. land VARCHAR(5) DEFAULT 'DE',
  9. PRIMARY KEY (id)
  10. );

Daten einfügen (nur Pflichtfelder)

Bei dem ersten INSERT werden von den vier Spalten nur die drei Pflichtfelder (die Spalten mit dem NOT NULL Constraint) eingefügt. Die vierte Spalte LAND fehlt in dem Einfügebefehl. Damit die Datenbank nun weiß, welcher Wert welcher Spalte zugeordnet werden soll, müssen die Spaltennamen explizit angegeben werden.


Listing 2:

  1. INSERT INTO adresse
  2. (id, vorname, name ) VALUES
  3. (1, 'Vorname-1','Name-1');
  4. SELECT * FROM adresse;
  5. +----+-----------+--------+------+
  6. | id | vorname | name | land |
  7. +----+-----------+--------+------+
  8. | 1 | Vorname-1 | Name-1 | DE |
  9. +----+-----------+--------+------+
  10. 1 row in set (0.00 sec)
  11. mysql>

Die beim INSERT-Befehl nicht angesprochene Spalte LAND erhält wie gewünscht den Defaultwert DE. Bis hier ist noch alles klar, es gibt auch noch andere Möglichkeiten, Daten in die Tabelle ADRESSE einzufügen. Häufig werden Klassen und Modelle verwendet, um auf Datenbanktabellen zuzugreifen und dann werden häufig komplette INSERT-Befehle (also mit allen Spalten) generiert.


Daten einfügen (alle Felder)

Hier drei weitere Beispiele, wie der INSERT-Befehl aussehen könnte. Da hierbei alle Tabellenspalten angesprochen werden, müssen die Spalten nicht mehr explizit aufgelistet werden. Trotzdem empfiehlt sich diese Auflistung aller Spalten, denn sollte die Tabelle später einmal um neue Spalten erweitert werden, wären alle vorher funktionierenden INSERT-Befehle plötzlich falsch.

Listing 3:

  1. INSERT INTO adresse
  2. (id, vorname, name, land ) VALUES
  3. (2, 'Vorname-2','Name-2', 'EU'),
  4. (3, 'Vorname-3','Name-3',DEFAULT),
  5. (4, 'Vorname-4','Name-4',NULL);
  6. SELECT * FROM adresse
  7. ORDER BY id;
  8. +----+-----------+--------+------+
  9. | id | vorname | name | land |
  10. +----+-----------+--------+------+
  11. | 1 | Vorname-1 | Name-1 | DE |
  12. | 2 | Vorname-2 | Name-2 | EU |
  13. | 3 | Vorname-3 | Name-3 | DE |
  14. | 4 | Vorname-4 | Name-4 | NULL | <== NULL anstatt DEFAULT 'DE'
  15. +----+-----------+--------+------+
  16. 4 rows in set (0.01 sec)

Wie schön zu sehen ist, hat der Datensatz (ID = 4) nun einen NULL Wert in der Spalte LAND, obwohl wir DEFAULT 'DE' definiert haben. Was nun?


TRIGGER als Sicherheitsgurt

Als Lösung bietet sich der BEFORE INSERT Trigger an. Damit wird vor dem eigentlichen Schreiben in die Tabelle noch eine zusätzliche Überprüfung - ähnlich einem CHECK Constraint - eingebaut.

Listing 4:

  1. DELIMITER $$
  2. CREATE TRIGGER adresse_trigger_insert_check
  3. BEFORE INSERT ON adresse
  4. FOR EACH ROW BEGIN
  5. IF NEW.land IS NULL THEN
  6. SET NEW.land := 'DE';
  7. END IF;
  8. END$$
  9. DELIMITER ;

Weitere Testdaten einfügen

Testen wir unsere bisherigen INSERT-Befehle nochmal mit neuen Daten.


Listing 5:

  1. INSERT INTO adresse
  2. (5, 'Vorname-5','Name-5');
  3. INSERT INTO adresse
  4. (id, vorname, name, land ) VALUES
  5. (6, 'Vorname-6','Name-6', 'EU'),
  6. (7, 'Vorname-7','Name-7',DEFAULT),
  7. (8, 'Vorname-8','Name-8',NULL);
  8. SELECT * FROM adresse
  9. ORDER BY id;
  10. +----+-----------+--------+------+
  11. | id | vorname | name | land |
  12. +----+-----------+--------+------+
  13. | 1 | Vorname-1 | Name-1 | DE |
  14. | 2 | Vorname-2 | Name-2 | EU |
  15. | 3 | Vorname-3 | Name-3 | DE |
  16. | 4 | Vorname-4 | Name-4 | NULL |
  17. | 5 | Vorname-5 | Name-5 | DE |
  18. | 6 | Vorname-6 | Name-6 | EU |
  19. | 7 | Vorname-7 | Name-7 | DE |
  20. | 8 | Vorname-8 | Name-8 | DE | <== jetzt DEFAULT 'DE'
  21. +----+-----------+--------+------+
  22. 8 rows in set (0.00 sec)
  23. mysql>

Wie an dem Datensatz (ID = 8) zu sehen ist, hat der Trigger den NULL Wert erkannt und den DEFAULT Wert eingesetzt.


Resumee

Mit TRIGGERn lassen sich sehr schön zusätzliche Überprüfungen realisieren. Ein kleiner Nachteil ist, dass die DEFAULT DE Regel jetzt an zwei Stellen definiert ist. Im CREATE TABLE und in dem BEFORE INSERT Trigger.




Sitemap - Inhaltsverzeichnis

© 2002-2016 by Thomas Wiedmann : (Stand : 11.01.2015).