Wie funktionieren UPDATE- und INSERT-Constraints?
*Markus
- datenbank
0 Vinzenz Mai0 Tom0 *Markus0 Vinzenz Mai0 *Markus0 Vinzenz Mai0 *Markus
Hallo,
ich habe folgendes Datenmodell angelegt, wo ich bestimmte Contraints gesetzt habe:
Wie ein DELETE-Contraint funktioniert, ist mir klar. Was kann ich aber mit den UPDATE- und INSERT-Contraints tun? INSERTs oder UPDATEs über mehrere Tabellen funktionieren doch von der Syntax gar nicht. Wann kann ich diese Contraints benutzen?
Markus
Hallo Markus,
ich habe folgendes Datenmodell angelegt, wo ich bestimmte Contraints gesetzt habe:
und wie schon mehrfach nachgefragt hast Du auch dieses Mal vergessen, irgendwelche Informationen zum verwendeten Datenbankmanagementsystem und in diesem Fall besonders wichtig zur verwendeten Modelliersoftware zu machen.
Wie ein DELETE-Contraint funktioniert, ist mir klar. Was kann ich aber mit den UPDATE-
natürlich das gleiche wie bei DELETE :-)
Wenn Du den Wert eines Primärschlüssels änderst, der in einer anderen Tabelle referenziert wird, na was ist dann mit dem Wert in der Fremdschlüsselspalte?
Verweist er noch auf einen gültigen Wert?
und INSERT-Contraints tun?
Weder MS SQL-Server 2005 (und älter) noch PostgreSQL 8.3 (und älter) kennen eine ON-INSERT-Klausel im Zusammenhang mit FOREIGN-KEY-CONSTRAINTS.
INSERTs oder UPDATEs über mehrere Tabellen funktionieren doch von der Syntax gar nicht.
Warum nicht? Sicher geht das. Vielleicht nicht in jedem DBMS. Es gibt DBMS, die INSERTS und UPDATES über mehrere Tabellen erlauben, ein Beispiel wäre MS Access. Das Stichwort in diesem Zusammenhang heißt View.
Freundliche Grüße
Vinzenz
Hello,
Warum nicht? Sicher geht das. Vielleicht nicht in jedem DBMS. Es gibt DBMS, die INSERTS und UPDATES über mehrere Tabellen erlauben, ein Beispiel wäre MS Access. Das Stichwort in diesem Zusammenhang heißt View.
MS Access ist kein DBMS sondern ein universelles Datenbank-Frontend
Wenn Du meinst, dass die JET-Engine das kann, müsstest Du das auch sagen, denn MS-ACCESS arbeitet auch mit MS-SQL oder anderen SQL-Datenbanksystemen zusammen
Ein harzliches Glückauf
Tom vom Berg
http://bergpost.annerschbarrich.de
.
Hallo Markus,
ich habe folgendes Datenmodell angelegt, wo ich bestimmte Contraints gesetzt habe:
und wie schon mehrfach nachgefragt hast Du auch dieses Mal vergessen, irgendwelche Informationen zum verwendeten Datenbankmanagementsystem und in diesem Fall besonders wichtig zur verwendeten Modelliersoftware zu machen.
Ach, du hast recht. PostgreSQL 8.3 und das Tool ist ERwin 1.1.
Wenn Du den Wert eines Primärschlüssels änderst, der in einer anderen Tabelle referenziert wird, na was ist dann mit dem Wert in der Fremdschlüsselspalte?
Ich weiß nicht, wie mir das helfen soll. Ich füge ja neue Werte und ändere nicht irgendwelche Primärschlüssel.
Warum nicht? Sicher geht das. Vielleicht nicht in jedem DBMS. Es gibt DBMS, die INSERTS und UPDATES über mehrere Tabellen erlauben, ein Beispiel wäre MS Access. Das Stichwort in diesem Zusammenhang heißt View.
Beim generieren der View komme ich trotzdem nicht nur mit einer Abfrage aus, wenn ich in 4 Tabellen INSERTen muss. Deswegen verstehe ich nicht ganz, wie mir das weiterhilft.
Markus
Hallo Markus,
Ach, du hast recht. PostgreSQL 8.3 und das Tool ist ERwin 1.1.
Danke.
Wie ein DELETE-Contraint funktioniert, ist mir klar. Was kann ich aber mit den UPDATE-
natürlich das gleiche wie bei DELETE :-)
Wenn Du den Wert eines Primärschlüssels änderst, der in einer anderen Tabelle referenziert wird, na was ist dann mit dem Wert in der Fremdschlüsselspalte?Ich weiß nicht, wie mir das helfen soll. Ich füge ja neue Werte und ändere nicht irgendwelche Primärschlüssel.
Ich weiß nicht, wo Dein Verständnisproblem ist.
Wir betrachten den FOREIGN-KEY-CONSTRAINT mit der ON-UPDATE-Klausel. Dort gilt, wie ich bereits schrieb, das gleiche wie für ON DELETE. Genau für den Fall, dass jemand den referenzierten Primärschlüssel ändert, irgendwelche anderen Werte in anderen Spalten interessieren hier natürlich nicht.
Nochmals: Der FOREIGN-KEY-CONSTRAINT mit ON UPDATE behandelt genau den Fall, dass in der Parenttabelle ein Primärschlüsselwert geändert wird, für den es Verweise in der Childtabelle gibt. Wenn Du das zulässt und in der Childtabelle nichts änderst, dann hast Du in der Childtabelle (mindestens) einen verwaisten Eintrag, d.h. zu dem Wert in der Fremdschlüsselspalte gibt es keinen passenden Wert in der Primärschlüsselspalte der referenzierten Tabelle. Genau der gleiche Effekt, als wäre der entsprechende Eintrag in der referenzierten Tabelle gelöscht worden.
Warum nicht? Sicher geht das. Vielleicht nicht in jedem DBMS. Es gibt DBMS, die INSERTS und UPDATES über mehrere Tabellen erlauben, ein Beispiel wäre MS Access. Das Stichwort in diesem Zusammenhang heißt View.
Beim generieren der View komme ich trotzdem nicht nur mit einer Abfrage aus, wenn ich in 4 Tabellen INSERTen muss. Deswegen verstehe ich nicht ganz, wie mir das weiterhilft.
Wie ich bereits schrieb, gar nicht:
Weder MS SQL-Server 2005 (und älter) noch PostgreSQL 8.3 (und älter) kennen eine ON-INSERT-Klausel im Zusammenhang mit FOREIGN-KEY-CONSTRAINTS.
Bei PostgreSQL sind bis zur aktuellen Version Views übrigens readonly, wie Du der Doku entnehmen kannst.
Was Deine Modelliersoftware Dir zu INSERT hier anbietet, sollte deren Dokumentation zu entnehmen sein.
Freundliche Grüße
Vinzenz
Hallo,
Nochmals: Der FOREIGN-KEY-CONSTRAINT mit ON UPDATE behandelt genau den Fall, dass in der Parenttabelle ein Primärschlüsselwert geändert wird, für den es Verweise in der Childtabelle gibt. Wenn Du das zulässt und in der Childtabelle nichts änderst, dann hast Du in der Childtabelle (mindestens) einen verwaisten Eintrag, d.h. zu dem Wert in der Fremdschlüsselspalte gibt es keinen passenden Wert in der Primärschlüsselspalte der referenzierten Tabelle. Genau der gleiche Effekt, als wäre der entsprechende Eintrag in der referenzierten Tabelle gelöscht worden.
Ok, alles klar. Ich dachte zuerst, ich hätte vielleicht irgend eine Möglichkeit, UPDATEs auf diese Weise zu vereinfachen.
Übrigens schreibt mir Erwin die UPDATE-Constraints gar nicht ins SQL-Script:
p_k_kunde SERIAL NOT NULL,
p_produktbezeichnung VARCHAR(20) NOT NULL,
p_preis FLOAT(2) NOT NULL
);
CREATE UNIQUE INDEX XPKPreis
ON Preis
(
p_id
);
CREATE TABLE Preiskategorie
(pk_id CHAR NOT NULL,
pk_bezeichnung VARCHAR(20) NOT NULL
);
CREATE UNIQUE INDEX XPKPreiskategorie
ON Preiskategorie
(
pk_id
);
ALTER TABLE Kunde
ADD PRIMARY KEY (k_id)
;
ALTER TABLE Preis
ADD PRIMARY KEY (p_id)
;
ALTER TABLE Preiskategorie
ADD PRIMARY KEY (pk_id)
;
ALTER TABLE Preis
ADD CONSTRAINT kategorie_kunde FOREIGN KEY (p_pk_preiskategorie)
REFERENCES Preiskategorie
ON DELETE SET NULL
;
ALTER TABLE Preis
ADD CONSTRAINT preis_kunde FOREIGN KEY (p_k_kunde)
REFERENCES Kunde
ON DELETE CASCADE
;
Es ist aber eh besser so. Es hat ja m.M.n. auch keinen Sinn, ein Konzept zu entwickeln, wo inkonsistente Daten entstehen könnten.
Markus
Hallo Markus,
Es ist aber eh besser so. Es hat ja m.M.n. auch keinen Sinn, ein Konzept zu entwickeln, wo inkonsistente Daten entstehen könnten.
ON UPDATE CASCADE verhindert genau diese Inkosistenzen, wobei ich der Ansicht bin, dass man es im Normalfall vermeiden sollte, Inhalte von Primärschlüsselspalten zu verändern. Das ist der große Vorteil von künstlichen Schlüsseln, denen man _keine_ zusätzliche Information aufbürdet.
Freundliche Grüße
Vinzenz
Hallo,
ON UPDATE CASCADE verhindert genau diese Inkosistenzen, wobei ich der Ansicht bin, dass man es im Normalfall vermeiden sollte, Inhalte von Primärschlüsselspalten zu verändern. Das ist der große Vorteil von künstlichen Schlüsseln, denen man _keine_ zusätzliche Information aufbürdet.
Also ich habe das Script, das ich postete, genauso eingelesen, und kann auch ohne diese Constraints keine Schlüssel UPDATEen, wenn diese noch von anderen Tabellen referenziert werden. Ich habe es von beiden Richtungen probiert. Parent-Child, Child-Parent, und nicht funktioniert es (zum Glück).
Markus