2012-12-07 51 views
1
customers: 
+------------+--------------+ 
| cid  | Name   | 
+------------+--------------+ 
| 1   | Bob   | 
| 2   | John   | 
| 3   | Jane   | 
+------------+--------------+ 
accounts: 
+------------+--------------+ 
| aid  | type   | 
+------------+--------------+ 
| 1   | Checking  | 
| 2   | Saving  | 
| 3   | Checking  | 
+------------+--------------+ 
transactions: 
+------------+--------------+--------------+--------------+ 
| tid  | cid   | aid   | type   | 
+------------+--------------+--------------+--------------+ 
| 1   | 1   | 1   | Open   | 
| 2   | 2   | 3   | Open   | 
| 3   | 1   | 2   | Open   | 
| 4   | 2   | 3   | Deposit  | 
+------------+--------------+--------------+--------------+ 

我試圖編寫一個觸發器,用於在新帳戶成功打開時寫入日誌表。當新帳戶打開時插入到表中的觸發器

現在我有這樣的:

CREATE OR REPLACE TRIGGER acc_opened 
BEFORE INSERT ON transactions 
FOR EACH ROW 
DECLARE 
    c_name customers.name%TYPE; 
BEGIN 
    IF :new.type = 'Open' THEN 
     SELECT name into c_name 
     FROM customers c 
     WHERE c.cid = :new.cid; 

     INSERT INTO logs (who, what) VALUES (c_name, 'An account has been opened'); 
END; 
/ 

,我有不工作,不知道從哪裏何去何從的代碼。

觸發完成,但火災時,我收到此錯誤信息:

PLS-00103:出現符號「END」在需要下列之一時:(開始的情況下宣佈退出用於轉到如果環模空編譯提高收益選擇更新而與< <繼續關閉當前刪除獲取鎖芯打開回滾保存點設置SQL EXECUT提交FORALL合流管清洗

+1

你能否澄清「不工作」的意思?你有錯誤嗎?如果是這樣,有什麼錯誤?這是編譯錯誤還是運行時錯誤? –

+0

對不起,剛添加了錯誤。 – user1378863

回答

0

與您previous question,如果要引用新行的特定列的數據,你需要使用:new僞記錄。所以,至少,

SELECT cid 
    INTO c_id 
    FROM transactions t 
WHERE t.aid = aid; 

將需要

SELECT cid 
    INTO c_id 
    FROM transactions t 
WHERE t.aid = :new.aid; 

除此之外,你肯定行中transactions表中的行插入accounts故事之前就存在?假設你有正常的外鍵約束,我通常會希望你在將表插入到transactions表之前插入一行到accounts表中。

名稱transactions也似乎很奇怪。如果這實際上只是將客戶ID映射到帳戶ID,那麼transactions似乎是一個相當糟糕的名字。如果該表實際存儲交易,我不確定爲什麼它會有客戶ID。但是,如果它確實存儲交易,則必須有其他表將客戶映射到帳戶。

在你更新的觸發,你缺少的END IF聲明

CREATE OR REPLACE TRIGGER acc_opened 
    BEFORE INSERT ON transactions 
    FOR EACH ROW 
DECLARE 
    c_name customers.name%TYPE; 
BEGIN 
    IF :new.type = 'Open' 
    THEN 
    SELECT name 
     into c_name 
     FROM customers c 
    WHERE c.cid = :new.cid; 

    INSERT INTO logs (who, what) 
     VALUES (c_name, 'An account has been opened'); 
    END IF; 
END; 
+0

我絕對同意。我也嘗試過:new.aid,但它仍然行不通。教授給了我們這個模式,而且設計的很糟糕......你說得對,它應該在交易之前先插入賬戶。但是架構無法從帳戶表中獲取客戶信息。 – user1378863

+0

@ user1378863 - 「仍然行不通」並不能說明我們太多 - 你是否在說同一行上出現同樣的錯誤?還是你得到一個不同的錯誤?或者你在說別的嗎?如果你先插入'accounts'表,然後插入'transactions'表,'transactions'實際上是將客戶映射到賬戶而不是存儲事務,則觸發器需要在'transactions'表上定義,而不是'帳戶'表。 –

+0

而「交易」表確實存儲交易,但它是唯一將客戶映射到「帳戶」的表... – user1378863

相關問題