2013-04-02 116 views
0

我正在尋找觸發器的幫助。通過觸發器更新pl/sql中多個表的記錄

我有如下表格。

CREATE TABLE Autorzy(Id_autora numeric(5), Imie varchar(15), Nazwisko varchar(20), constraint auth_pk PRIMARY KEY (Id_autora)); 
CREATE TABLE Ksiazki(ISBN numeric(10) PRIMARY KEY, Wydawca varchar(30), Tytul varchar(70), Rok numeric(4)); 
CREATE TABLE Autorstwa (ISBN numeric(10) references Ksiazki, Id_autora numeric(5) references Autorzy); 
CREATE TABLE Tematy (Nrtematu numeric(4) PRIMARY KEY, Nazwa varchar(20), Wyjasnienie varchar (100)); 
CREATE TABLE Na_temat(ISBN numeric(10) references Ksiazki, Nrtematu numeric(10) references Tematy); 

create sequence id_autora_seq 
start with  1 
increment by 1 
; 

create sequence isbn_seq 
    start with 1 
    increment by 1 
;  

我必須實現表Autorzy,Ksiazki和Autorstwa的插入。

如下

insert into Autorzy 
values(Id_autora_seq.nextval, 'Jan', 'Mak'); 
insert into Ksiazki 
values (isbn_seq.nextval, 'ABC', 'Poradnik', 2010); 

我不知道如何使更新Autorstwa表我已經prepered插入。

我試着用觸發器作爲belowe

create or replace 
trigger Autorstwa_auth 
    after insert or update on keiishi.Autorzy 
    for each row 
begin 
    insert into Autorstwa (Id_autora) 
    values (:new.id_autora); 
end; 

create or replace 
trigger Autorstwa_ks 
    after insert or update on keiishi.Ksiazki 
    for each row 
begin 
    insert into Autorstwa (ISBN) 
    values (:new.ISBN); 
end; 

它創造了Autorstwa表兩排和它的對我來說是不可接受的。

任何人都可以解釋我如何使多個表更新觸發器?

或者其他一些方法我可以做到嗎?

在此先感謝。

問候

Keiishi

回答

1

您可以嘗試使用MERGE語句改寫你的觸發器。我會做一個,你可以做另一個。 :-)

CREATE OR REPLACE TRIGGER AUTORSTWA_AUTH 
    AFTER INSERT OR UPDATE ON KEIISHI.AUTORZY 
    FOR EACH ROW 
BEGIN 
    MERGE INTO AUTORSTWA a 
    USING(SELECT :NEW.ID_AUTORA FROM DUAL) d 
     ON (a.ID_AUTORA = d.ID_AUTORA) 
    WHEN NOT MATCHED THEN 
     INSERT (ID_AUTORA) 
     VALUES (:NEW.ID_AUTORA); 
END AUTORSTWA_AUTH; 

寫這樣一來,MERGE語句只會導致行插入AUTORSTWA_AUTH如果沒有匹配的行已經存在。如果你對另一個觸發器做同樣的事情,你應該只爲給定的鍵值插入一行。

分享和享受。

+0

我不明白這是如何工作的:它似乎有在該模式中Autorstwa FK約束,一個人如何能做到的插入該表中而不知道必須使用哪些鍵? – didierc

+0

嗨鮑勃感謝的答案:) 我已經試過這和它的一些變化工作後, 使用(選擇:NEW.ID_AUTORA FROM DUAL) ON(a.ID_AUTORA =新:ID_AUTORA) WHEN NOT MATCHED THEN INSERT( ID_AUTORA) VALUES(:NEW.ID_AUTORA); 但不幸的是我仍然得到兩行不是一個。 – Keiishi

+0

迪迪埃可以告訴你,'不知道鑰匙'是什麼意思?我仍然在學習這些東西,可能我錯過了一些東西。我看到,'如果我有參考,那麼它的列與確切的名稱作爲一個即時通訊引用'。還是我錯了? – Keiishi

0

我想你是錯誤地設置關係。爲了使用觸發器更新第三個表格,第一個和第二個表格的值應該是兩者之間的關係,或者應該有一個表格連接第一個和第二個表格。

0

我改變表Autorstwa到

CREATE TABLE Autorstwa (ISBN numeric(10) references Ksiazki(ISBN), Id_autora numeric(5) references Autorzy(Id_Autora), constraint pk_auto PRIMARY KEY (ISBN, Id_autora)); 

至於插入新值到該表中,在最後,我使用的正常插入

insert into Autorstwa 
select max(ISBN), max(Id_Autora) from Ksiazki , Autorzy 

因此,我可以採取從Ksiazki和Autorzy最新的值。

我需要它的確定

在那一刻,我沒有時間,使程序這一點,但我會做一個和它張貼在這裏,我會得到一些自由時間

再次感謝大家的意見:)

0

它爲我

CREATE OR REPLACE VIEW new_book AS 
    SELECT k.ISBN, k.Wydawca, k.Tytul, k.Rok, 
      a.Id_Autora, a.Imie, a.Nazwisko 
    FROM Autorzy a, Ksiazki k, Autorstwa au 
    WHERE a.id_autora = (SELECT au.Id_Autora FROM Autorstwa au WHERE au.ISBN = (SELECT k.ISBN FROM Ksiazki k)); 

CREATE OR REPLACE TRIGGER new_book_insert 
    INSTEAD OF INSERT ON new_book 
    DECLARE 
    duplicate_info EXCEPTION; 
    PRAGMA EXCEPTION_INIT (duplicate_info, -00001); 
    BEGIN 

    INSERT INTO Autorzy (Id_Autora, Imie, Nazwisko) 
    VALUES (
    :new.Id_Autora, 
    :new.Imie, 
    :new.Nazwisko); 

    INSERT INTO Ksiazki (ISBN, Wydawca, Tytul, Rok) 
    VALUES (
    :new.ISBN, 
    :new.Wydawca, 
    :new.Tytul, 
    :new.Rok); 

    INSERT INTO Autorstwa (ISBN, Id_Autora) 
    VALUES (
    :new.ISBN, 
    :new.Id_Autora); 
    EXCEPTION 
    WHEN duplicate_info THEN 
     RAISE_APPLICATION_ERROR (
     num=> -20107, 
     msg=> 'Duplicate Id_Autora or ISBN'); 
    END new_book_insert;