Fehler in BEFORE DELETE Trigger

MarkusSalb

Neuer Benutzer
Beiträge
1
Hallo zusammen,

ich beschäftige mich vor kurzem mit Datenbanken und daher kann noch nicht alle Fehler selber erkennen. Könnte mir wahrscheinlich jemand mit Trigger helfen?
Es gibt Rezeptdatenbank mit Tabelle "Rezept", "Speisekarte", "Anzahl_Rezepte". Rezepte, die in der Speisekarte stehen dürfen nicht gelöscht werden. Compiler ergibt immer Fehler: Fehler(8,4): PLS-00103: Encountered the symbol ";" when expecting one of the following: if
Wenn ich aber ";" lösche, ergeben sich mehrere Fehler.

DROP TABLE Speisekarte CASCADE CONSTRAINTS;
DROP TABLE Anzahl_Rezepte CASCADE CONSTRAINTS;
DROP TABLE Rezept CASCADE CONSTRAINTS;

CREATE TABLE Speisekarte(
Speisekarte_ID NUMBER(20) NOT NULL PRIMARY KEY,
Bezeichnung VARCHAR2(50)
);
CREATE TABLE Anzahl_Rezepte(
Speisekarte_ID NUMBER(20) NOT NULL,
Rezept_ID NUMBER(20) NOT NULL,
Preis NUMBER CONSTRAINT cc_preis CHECK (Preis > 0),
PRIMARY KEY (Speisekarte_ID, Rezept_ID)
);
CREATE TABLE Rezept(
Rezept_ID NUMBER(20) NOT NULL PRIMARY KEY,
Mitarbeiter_ID NUMBER(20),
Bezeichnung VARCHAR2(50),
Schlagwort VARCHAR (50),
Zubereitungsdauer NUMBER(20),
Freigabe VARCHAR2(10),
Rezept_Kategorie_ID NUMBER(20)
);
CREATE TRIGGER Rezept_in_Speisekarte
BEFORE DELETE
ON Rezept
FOR EACH ROW
DECLARE
Preis NUMBER;
BEGIN
SELECT Preis FROM Anzahl_Rezepte WHERE Rezept_ID = :eek:ld.Rezept_ID;
IF Preis != 0
THEN raise_application_error (-20000, 'Das Rezept kann nicht geloescht werden, da in der Speisekarte steht');
ELSE IF NO_DATA_FOUND THEN
NULL;
END;
 
Werbung:
Deine Idee, die referentielle Integrität zwischen den Tabellen zu sichern, ist per se nicht schlecht - nur falsch realisiert. Viel zu umständlich, denn 'richtige' Datenbanken können das Out-of-the-Box.

Code:
test=# create table rezept (rezept_id int primary key, name text);
CREATE TABLE
test=*# create table speisekarte (karte_id int primary key, rezept int references rezept, bezeichnung text);
CREATE TABLE
test=*# insert into speisekarte values (1,1,'rezept1');
FEHLER:  Einfügen oder Aktualisieren in Tabelle »speisekarte« verletzt Fremdschlüssel-Constraint »speisekarte_rezept_fkey«
DETAIL:  Schlüssel (rezept)=(1) ist nicht in Tabelle »rezept« vorhanden.
test=*# insert into rezept values (1,'rezept 1');
INSERT 0 1
test=*# insert into speisekarte values (1,1,'rezept1');
INSERT 0 1
test=*# delete from rezept where rezept_id = 1;
FEHLER:  Aktualisieren oder Löschen in Tabelle »rezept« verletzt Fremdschlüssel-Constraint »speisekarte_rezept_fkey« von Tabelle »speisekarte«
DETAIL:  Auf Schlüssel (rezept_id)=(1) wird noch aus Tabelle »speisekarte« verwiesen.
test=*#

Wie man sieht: du kannst weder in der Speisekarte auf ein nicht vorhandenes Rezept verweisen noch ein Rezept löschen, welches in der Speisekarte verwendet wird. Da ist keine Notwendigkeit, extra zu zählen, einen TRIGGER zu bauen etc. - einfach nur als Foreign Key Constraint definieren.
 
Werbung:
Moin,

vom bereits beschriebenen Vorgehen abgesehen, hier ein paar Hinweise zum Code:
- beim SELECT fehlt das INTO variable
- Exceptionhandling wird anders gemacht:
Code:
begin
...
exception
  when no_data_found then
...
end;
- Ein Primary Key ist implizit NOT NULL, die Spalte(n) müssen nicht nochmal als NOT NULL definiert werden.
 
Zurück
Oben