2015-10-27 34 views
0

我環顧四周,嘗試了一些我已閱讀的解決方案。我試圖創建一個pl/sql觸發器,如果​​符合一個子句,它會將數據從一個表複製到另一個表。我覺得我可能只是做一個愚蠢的語法錯誤,而不是一個完整的關鍵失敗,但會感謝一些幫助。PL/SQL觸發問題(從表1到表2複製數據)

create or replace TRIGGER TRG_APPLICATIONS 
BEFORE INSERT or UPDATE OF APP_ID, Status_id 
ON APPLICATIONS 
FOR EACH ROW 
BEGIN 

:new.APP_ID := SEQ_APP_ID.nextval; 
:new.APP_DATE := SYSDATE; 

IF STATUS_ID = 2 OR STATUS_ID = 5 OR STATUS_ID = 7 OR STATUS_ID = 8 THEN 
INSERT INTO APP_HISTORY 
SELECT SRN, STATUS_ID, APP_DATE 
FROM APPLICATIONS; 
END IF; 

END; 

這裏有錯誤

6 4 PLS-00201:標識符 'STATUS_ID' 必須聲明爲

6 1 PL/SQL:語句被忽略

+0

那麼錯誤是什麼? – Mihai

+0

你有什麼錯誤嗎?或者你的觸發器不工作? –

+0

看起來像我們只是猜測。因爲除了語法錯誤(錯過:新錯誤和錯誤插入),我們不知道你的查詢應該做什麼。 –

回答

2

一旦你注意,你需要參考值:NEW來獲取此插入或更新ID的狀態的當前值,然後你會打你的第二個錯誤 - 當內容不穩定時,您無法查詢觸發器所在的表。你會得到一個變異的表錯誤。更不用說,你在SELECT上沒有where子句,所以你會將所有的APPLICATIONS轉儲到APP_HISTORY中。我敢打賭,你想要的只是在更新之前複製行。當然插入前沒有行,所以沒有任何可複製的內容。或者你想在插入時將NEW值複製到HISTORY表中?

假設你想保持更新舊值,那麼你會:

create or replace TRIGGER TRG_APPLICATIONS 
BEFORE INSERT or UPDATE OF APP_ID, Status_id 
ON APPLICATIONS 
FOR EACH ROW 
BEGIN 

-- APP_ID better not be the PK or it is changing on UPDATE! 
-- IF you only want this value set once on INSERT, wrap it in an IF INSERTING ... END IF; structure 
:new.APP_ID := SEQ_APP_ID.nextval; 
:new.APP_DATE := SYSDATE; 

IF UPDATING AND (:NEW.STATUS_ID = 2 OR :NEW.STATUS_ID = 5 OR :NEW.STATUS_ID = 7 OR :NEW.STATUS_ID = 8) 
THEN 
    INSERT INTO APP_HISTORY (SRN, STATUS_ID, APP_DATE) 
    VALUES (:OLD.SRN, :OLD.STATUS_ID, :OLD.APP_DATE); 
END IF; 

END; 

在你觸發的第一個削減其他的想法 - 你的觸發器觸發的APP_ID的更新,但後來改變了APP_ID再次在觸發器內。因此,如果您的用戶界面設置了APP_ID值,然後使用該值插入相關記錄 - 您剛剛搞砸了。

+1

爲什麼只有'updated'?觸發器用於更新並插入 –

+0

通常,歷史表不包含當前行,這就是爲什麼我問他/她的意圖並在將OLD值複製到歷史記錄表之前解釋了我的答案的假設。我也解釋了變異表,並且我也質疑APP_ID爲什麼會在更新時發生變化。我當然希望它不是PK!無論如何,只要給我一個明顯的初學者儘可能多的信息。 –

+0

實際上,如果您查看觸發器聲明,它會觸發app_id的更新,然後在觸發器內更改app_id AGAIN。哎喲!第一次切割有太多的錯誤,所以人們需要停下來,喘口氣,並且對他們想要完成的事情有更清晰的定義。 –

0

可能是你需要添加NEW

IF :NEW.STATUS_ID = 2 OR :NEW.STATUS_ID = 5 
OR :NEW.STATUS_ID = 7 OR :NEW.STATUS_ID = 8 THEN 
    INSERT INTO APP_HISTORY (srn, status_id, app_date) 
    VALUES (:NEW.SRN, :NEW.STATUS_ID, :NEW.APP_DATE); 
END IF; 
+0

不要忘記冒號 - :NEW不是新的 –

+0

如果NEW.STATUS_ID = 2或NEW.STATUS_ID = 5或NEW.STATUS_ID = 7或新。 STATUS_ID = 8 THEN 產生此錯誤 編譯失敗,第6行(14:08:58)與編譯錯誤關聯的行號與第一個BEGIN語句相關。這隻影響數據庫觸發器的編譯。 PLS-00201:標識符'NEW.STATUS_ID'必須聲明編譯失敗,第6行(14:08:58)與編譯錯誤關聯的行號與第一個BEGIN語句相關。這隻影響數據庫觸發器的編譯。 PL/SQL:語句被忽略 –

+0

IF:new.STATUS_ID = 2 OR:new.STATUS_ID = 5 OR:new.STATUS_ID = 7 OR:new。STATUS_ID = 8 THEN 產生此錯誤 PL/SQL:ORA-00947:沒有足夠的值編譯失敗,第7行(14:07:38)與編譯錯誤關聯的行號與第一個BEGIN語句有關。這隻影響數據庫觸發器的編譯。 PL/SQL:SQL語句被忽略 如果我將問題修復爲:new。 –

0

檢查了這一點:

create or replace TRIGGER TRG_APPLICATIONS 
    BEFORE INSERT or UPDATE OF APP_ID, Status_id 
    ON APPLICATIONS 
    FOR EACH ROW 
BEGIN 

    :new.APP_ID := SEQ_APP_ID.nextval; 
    :new.APP_DATE := SYSDATE; 

    IF :new.STATUS_ID = 2 OR 
    :new.STATUS_ID = 5 OR 
    :new.STATUS_ID = 7 OR 
    :new.STATUS_ID = 8 THEN 

    INSERT INTO APP_HISTORY (srn, status_id, app_date) 
    values (:new.srn, :new.status_id, :new.app_date); 

END IF; 

END; 
+0

編譯失敗,第11行(14:11:22)行號與編譯錯誤相關的是與第一個BEGIN語句相關的。這隻影響數據庫觸發器的編譯。 PL/SQL:ORA-00947:值不足編譯失敗,第11行(14:11:22)與編譯錯誤關聯的行號與第一個BEGIN語句相關。這隻影響數據庫觸發器的編譯。 PL/SQL:SQL語句被忽略 –

+0

因此,也許你應該在插入語句處命名列,例如insert into app_history(column1,column2,column3)values(:new.srn,:new.status_id,:new.app_date) –

+0

你是什麼意思? –

相關問題