2016-03-27 115 views
-1

我有兩個表:觸發涉及兩個表的SQL

合同(球員,隊)

匹配(球員,球隊,比賽)

團隊是一個數字(1)從0到9

MATCHES中的屬性團隊必須與合同中的該參與者相同,或者少於1或1個。 (在比賽中,同一名球員可能會出現不止一次)。

我有一個觸發器,以檢查是否在比賽中所有球員的履行我前面提到

我已經試過了,但沒有找到狀態:

CREATE TRIGGER trigA 
    BEFORE INSERT OR UPDATE OF team on matches 
    FOR EACH ROW 
    DECLARE error EXCEPTION; 
    BEGIN 
    IF (:NEW.team!=contracts.team OR :NEW.team!=contracts.team +1 OR :NEW.team!=contracts.team -1) AND (:NEW.player) = contracts.player 
    THEN error; 
    END IF; 
    EXCEPTION 
    WHEN error THEN DBMS_OUTPUT.PUT_LINE('Invalid Team'); 
    END; 
/
+0

沒有。這是我第一次觸發兩張桌子,我不知道該怎麼辦。 – Dan

+0

從觸發器定義的外殼開始 - 事件,時間,範圍和上下文 - 並將其發佈到您的問題中。知道這將使下一部分更容易。 –

+0

此外,您已將此標籤標記爲「Oracle」和「MySQL」。您是使用這兩種產品,還是應該放下其中一個標籤? –

回答

0

在你觸發你需要查詢觸發器中的CONTRACTS表,查找滿足條件的CONTRACTS行。如果你發現至少有一件事情沒有問題。如果你不需要提出錯誤。

事情是這樣的:

CREATE TRIGGER MATCHES_BIU_TEAM 
    BEFORE INSERT OR UPDATE OF team on matches 
    FOR EACH ROW 
DECLARE 
    nContract_count NUMBER; 
BEGIN 
    SELECT COUNT(*) 
    INTO nContract_count 
    FROM CONTRACTS c 
    WHERE c.PLAYER = :NEW.PLAYER AND 
      c.TEAM BETWEEN :NEW.TEAM - 1 
        AND :NEW.TEAM + 1; 

    IF nContract_count = 0 THEN 
    RAISE_APPLICATION_ERROR(...); 
    END IF; 
END MATCHES_BIU_TEAM; 

去查查怎麼用RAISE_APPLICATION_ERROR提高其調用程序可以捕捉異常。這很重要,因爲如果發生異常確實發生了,您不希望僅在觸發器中的EXCEPTION處理程序中使其消失 - 它需要引發以便調用應用程序代碼可以處理它。

祝你好運。

+0

感謝您的評論! 我一直在尋找在線和我的結論寫: 「(...)IF nContract_count = 0,則 RAISE_APPLICATION_ERROR(-20000, '錯誤');(......)」 但我如果測試在壞的情況下工作,而不是。出現'錯誤'但在下一行給我另一個錯誤:「c.TEAM BETWEEN:NEW.TEAM - 1」 PD:在有效的情況下,它的工作 – Dan

+0

這是我的錯誤 http://i.stack.imgur .com/x6rvX.png – Dan

+0

@Dan:看來這正是你應該得到的錯誤。您已將PLAYER ='Peter',TEAM = 1和MATCH = 41插入到MATCHES中。您沒有包含來自CONTRACTS的數據,但我猜測CONTRACTS_AUX顯示了相同的信息。如果是這樣,那麼PLAYER ='Peter'和TEAM = 5的合約中就有價值。當觸發器觸發時,它會查找PLAYER ='Peter'的合同中的數據,並在0和2之間查找TEAM中的數據,並發現CONTRACTS中沒有匹配的數據,因此返回0作爲行計數。觸發器看到行計數爲0並引發異常-20000。 –

0

另一種方法是這樣的:

CREATE TRIGGER MATCHES_BIU_TEAM 
    BEFORE INSERT OR UPDATE OF team on matches 
    FOR EACH ROW 
DECLARE 
    matchTeam NUMBER; 
BEGIN 
    SELECT c.team 
    INTO matchTeam 
    FROM CONTRACTS c 
    WHERE c.player = :NEW.player; 

    IF matchTeam < :NEW.team - 1 OR matchTeam > :NEW.team + 1 THEN 
    RAISE_APPLICATION_ERROR(...); 
    END IF; 
END MATCHES_BIU_TEAM; 

這是假定)要的contracts.team值進行比較matches.team(鮑勃·賈維斯答案比較多項紀錄,contracts的值爲matches.team),以及b)每個玩家在contracts中只有一條記錄。

+0

感謝您的評論!但是,當我嘗試插入一行無效時,觸發器給我執行問題..不要告訴我只有我的RAISE_APPLICATION_ERROR 我理解你的觸發器,並且Bob Jarvis也觸發,但我不知道爲什麼不工作 – Dan

+0

當您編寫RAISE_APPLICATION_ERROR插入未完成? – Dan

+0

正確。提高錯誤會導致觸發失敗,從而導致觸發語句失敗。請參見[Oracle數據庫PL/SQL語言參考](http://docs.oracle.com)[複雜約束檢查的觸發器](http://docs.oracle.com/database/121/LNPLS/triggers.htm#CIHDDGGD)的.com /數據庫/ 121/LNPLS/toc.htm)。 –