2012-11-13 89 views
0

我有執行低於觸發一些問題:創建觸發器插入到另一個表

CREATE OR REPLACE TRIGGER AFTERINSERTCREATEBILL 
AFTER INSERT 
ON READING 
FOR EACH ROW 

DECLARE 

varReadNo Int; 
varMeterID Int; 
varCustID Varchar(10); 

BEGIN 

SELECT SeqReadNo.CurrVal INTO varReadNo FROM DUAL; 

Select MeterID INTO varMeterID 
From Reading 
Where ReadNo = varReadNo; 

Select CustID INTO varCustID 
From Address A 
Join Meter M 
on A.postCode = M.postCode 
Where M.MeterID = varMeterID; 

INSERT INTO BILL VALUES 
(SEQBILLNO.NEXTVAL, SYSDATE, 'UNPAID' , 100 , varCustID , SEQREADNO.CURRVAL); 

END; 

錯誤消息:

*原因:觸發器(或所引用用戶定義PLSQL函數在 這條語句)試圖查看(或修改)一個表,該表在被髮布它的語句修改的過程中是 。

*操作:重寫觸發器(或函數),使其不讀取該表。

這是否意味着我不想從表Reading中檢索任何細節?

我相信這個問題會發生,因爲我從表中讀取檢索數據,同時它插入值:

SELECT SeqReadNo.CurrVal INTO varReadNo FROM DUAL; 

Select MeterID INTO varMeterID 
From Reading 
Where ReadNo = varReadNo; 

它的存在,無論如何要解決這個問題?還是有更好的方法來做到這一點?在輸入表之後,我需要在表格BILL中插入一個新的行讀取ReadNo需要引用我剛插入的ReadNo的位置。

+0

您需要找出'編譯/授權失敗的觸發器'期間發生了什麼錯誤然後給我們那個錯誤信息。如果您有TOAD,請轉到Schema Browser中的觸發器,右鍵單擊並編譯,它應該會顯示錯誤消息。如果你只是在SQLPLUS中運行腳本,我想它應該給你一個錯誤信息。另外我建議你在你的INSERT語句中添加一個列表來減少可能的錯誤。 –

+0

你可以嘗試在觸發器外面插入表'BILL'嗎?並檢查您是否具有您在觸發器中使用的表的讀/寫權限。這將幫助您調試問題。 – user75ponic

+0

我試圖插入表格比爾無觸發器,它似乎工作正常。我試着對觸發器中的值進行硬編碼,它的工作也很好,我相信問題在於下面的語句:SELECT SeqReadNo.CurrVal INTO varReadNo FROM DUAL; Select MeterID INTO varMeterID From Reading Where ReadNo = varReadNo; – FirstTimer

回答

4

您不能檢索連續觸發來自同一個表中的記錄。你可以使用new和old來訪問實際記錄中的值(這是你的情況嗎?)。如果您需要查詢從閱讀表中的其他記錄,你必須使用語句觸發器,行觸發器和PLSQL集合的組合觸發然後可以改寫爲

CREATE OR REPLACE TRIGGER AFTERINSERTCREATEBILL 
AFTER INSERT 
ON READING 
FOR EACH ROW 

DECLARE 

    varCustID Varchar(10); 

BEGIN 

    Select CustID INTO varCustID 
    From Address A 
    Join Meter M 
     on A.postCode = M.postCode 
    Where M.MeterID = :new.MeterID; 

    INSERT INTO BILL VALUES 
    (SEQBILLNO.NEXTVAL, SYSDATE, 'UNPAID' , 100 , varCustID , SEQREADNO.CURRVAL); 

END; 

。這方面的好例子是AskTom.oracle.com

+3

甚至可以將插入和選擇組合到一個語句中。 –

0

確保您具有所有表格的必要權限並訪問您在插入中使用的序列。

我還沒有在一段時間內完成Oracle,但您也可以嘗試查詢dba_errors(或all_errors)以嘗試獲取有關您的SP未編譯的原因的更多信息。

某事的調整:

SELECT * FROM dba_errors WHERE owner = 'THEOWNER_OF_YOUR_SP'; 
0

在觸發器中添加異常處理並查看發生了什麼,通過這樣做會很容易跟蹤異常。

CREATE OR REPLACE TRIGGER AFTERINSERTCREATEBILL 
AFTER INSERT 
ON READING 
FOR EACH ROW 

DECLARE 

    varCustID Varchar(10); 

BEGIN 

    -- your code 

EXCEPTION 
    WHEN NO_DATA_FOUND 
    THEN 
     DBMS_OUTPUT.PUT_LINE(TO_CHAR(SQLERRM(-20299))); 
    WHEN OTHERS THEN 
    DBMS_OUTPUT.PUT_LINE(TO_CHAR(SQLERRM(-20298))); 

END; 
+0

我測試了例外;新的讀數將被插入,但是賬單不會被創建。解決這個問題的任何想法? – FirstTimer

+0

賬單到底是什麼?一些身份證號碼正在生成? – user75ponic

0

我們可以結合insert和select語句

CREATE OR REPLACE TRIGGER AFTERINSERTCREATEBILL 
AFTER INSERT 
ON READING 
FOR EACH ROW 

DECLARE 

varCustID Varchar(10); 

BEGIN 

insert into bill 
values 
select SEQBILLNO.NEXTVAL, 
     SYSDATE, 
     'UNPAID' , 
     100 , 
     CustID,SEQREADNO.CURRVAL 
From Address A 
Join Meter M 
on A.postCode = M.postCode 
Where M.MeterID = :new.MeterID; 

END; 

嘗試上面的代碼。

相關問題