2016-07-20 99 views
0

Ich habe 2 Tabellen ‚Label‘ und 'MusikerOracle-Trigger auf VARCHAR Werten arbeiten nicht

CREATE TABLE label 
(labId varchar(10) NOT NULL PRIMARY KEY, 
labName varchar(20) NOT NULL 
); 



CREATE TABLE musician 
(musId varchar(10) NOT NULL PRIMARY KEY, 
musName varchar(30) NOT NULL, 
labId varchar(10) NOT NULL, 
CONSTRAINT MusLabel FOREIGN KEY (labId) REFERENCES label(labId) 
); 

I einen Trigger geschaffen, um die Anzahl von Musikern zu begrenzen, ein Etikett 5 innerhalb eines Bereichs von 1 haben kann ; so dass beispielsweise ein Etikett x kann nicht sechs Musiker haben:

CREATE OR REPLACE TRIGGER before_musician_insert 
BEFORE INSERT ON musician 
FOR EACH ROW 
DECLARE 
total integer; 
BEGIN 
SELECT COUNT(*) INTO total 
FROM musician, label 
WHERE musician.labId=label.labId; 
IF (total < 0 OR total > 5) 
THEN 
DBMS_OUTPUT.PUT_LINE('Invalid'); 
END IF; 
END; 
/

Wenn ich einen sechsten Musiker in die Tabelle mit der gleichen Etikett ID einfügen, die Insert-Anweisung nicht ‚Auslöser‘ der Trigger und der sechste Wert hinzugefügt werden an den Tisch. Ich weiß nicht, wie ich das beheben kann. Ich habe eine Check-Einschränkung versucht, aber mit Varchar-Werten funktioniert es auch nicht.

Ich schätze Ihre Hilfe.

+0

Ihr Trigger macht keinen Sinn. Zunächst einmal ist es auf dem Musikertisch, aber Sie beschreiben das Problem als Etiketten. –

+0

Ist dies für eine Klasse, in der Sie einen Trigger verwenden müssen? Dies ist nicht gut für einen Trigger (besonders, wenn Sie mehrere Benutzer erwarten) und die Anforderung ist nicht sehr sinnvoll - was passiert, wenn ein Label einen 6. Musiker unterschreiben möchte? Wenn Sie das wirklich durchsetzen möchten, sollten Sie das Datenmodell besser ändern. –

+0

@Justin Cave Ja, es ist eigentlich eine Aufgabe für eine Klasse. Ich habe mich gefragt, ob ich in diesem Fall eine Checkbeschränkung verwenden könnte, und wenn ja wie? – omar

Antwort

0

Ihr Code weist mehrere Probleme auf. Zum Beispiel greift es nicht auf :new zu. Der Auslöser befindet sich auf dem falschen Tisch. Es hat keine Fehlergenerierung.

Ich könnte so etwas wie dies vorschlagen:

CREATE OR REPLACE TRIGGER before_labels_insert 
BEFORE INSERT ON labels 
FOR EACH ROW 
DECLARE 
    v_total integer; 
    user_xcep EXCEPTION; 
    PRAGMA EXCEPTION_INIT(user_xcep, -20001); 
BEGIN 

    SELECT COUNT(*) INTO v_total 
    FROM labels l 
    WHERE l.labId = :new.labId; 
    IF (v_total >= 5) THEN 
     DBMS_OUTPUT.PUT_LINE('Invalid'); 
     RAISE user_xcep 
    END IF; 
END; 
+0

Dieser Trigger generiert 'muting table error', weil dieselbe Tabelle, an der eine auslösende Anweisung arbeitet, abgefragt wird. Ja 'vor dem Einfügen' Zeilenebenentrigger verzeiht eine einfache' insert in .. values ​​() 'Anweisung, aber' in select ... from' Anweisung einfügen wird fehlschlagen. Außerdem denke ich, wenn ein Trigger erstellt werden muss, muss er auf dem "Musikertisch" erstellt werden. Basierend auf der Beschreibung von OP gibt es eine Beziehung zwischen Labels und Musikern. –

+0

@Gordon Linoff Ich bekomme das gleiche Ergebnis. Es erlaubt mir Werte> 5 in die Tabelle einzufügen. Vielleicht muss ich meine Bitte klarstellen: Was ich versuche zu tun, ist die Einfügung auf den Musikertisch zu beschränken, nicht umgekehrt, wie Nicholas Krasnov richtig bemerkte. – omar

0

Ihre Trigger ausgelöst VOR dem Einsatz, so dass der sechste Eintrag nicht existiert, wenn die Abfrage ausgeführt wird.

Wenn Sie einen Fehler bei der Eingabe des 6. Eintrags haben möchten, können Sie einen AFTER-Trigger (und einmal pro Anweisung anstelle von JEDER ZEILE) auslösen.