2012-01-07 64 views
2

我有一個語句級別的觸發器,只要在一個表(稱爲客戶)上執行INSERT UPDATE或DELETE操作時觸發。我想顯示一條消息(到DBMS_OUTPUT),其中包含插入/更新/刪除的行數。如何在語句觸發器中獲取語句影響的行數

我只想爲每個觸發語句寫一條消息,例如 '將4行插入customers表'中。

我如何可以訪問從內部觸發聲明受觸發語句的行數,即在XXX下面的代碼:

CREATE OR REPLACE TRIGGER customer_changes_trigger_2 
AFTER INSERT OR UPDATE OR DELETE ON customers 

DECLARE 
v_operation VARCHAR(10); 
v_number_rows NUMBER; 


BEGIN 

v_number := XXX; 

IF INSERTING THEN 
    v_operation := 'inserted'; 
END IF; 

IF UPDATING THEN 
    v_operation := 'updated'; 
END IF; 

IF DELETING THEN 
    v_operation := 'deleted'; 
END IF; 

DBMS_OUTPUT.PUT_LINE 
      (v_number_rows|| ' rows were ' || v_operation || ' from customers.'); 
END; 

無法找到文檔中任何東西,任何幫助不勝感激!

+0

爲什麼最初你想要'dbms_output'嗎?你會去那裏檢查每一次?此時用於調試的 – Ben 2012-01-07 14:37:02

+0

,稍後插入到表中。 – dav83 2012-01-07 14:39:20

+0

爲什麼不只是將觸發器更改爲'對於每一行'並插入到您的跟蹤表中,然後有一個單獨的查詢來總結它們? – Ben 2012-01-07 15:18:23

回答

4

一種方法是使用全局變量來跟蹤的行數,因爲沒有其他辦法從語句級觸發器獲取行計數。然後,您需要三個觸發器...一個語句級別在語句運行之前初始化該變量,一個行級別爲每行添加一個變量,一個語句級別使用您希望的行數。首先,設置變量和一些程序,以幫助它:

create or replace package PKG_ROWCOUNT is 
    NUMROWS number; 

    procedure INIT_ROWCOUNT; 

    procedure ADD_ONE; 

    function GET_ROWCOUNT 
    return number; 
end PKG_ROWCOUNT; 
/

create or replace package body PKG_ROWCOUNT as 
    procedure INIT_ROWCOUNT is 
    begin 
    NUMROWS := 0; 
    end; 

    procedure ADD_ONE is 
    begin 
    NUMROWS := Nvl(NUMROWS, 0) + 1; 
    end; 

    function GET_ROWCOUNT 
    return number is 
    begin 
    return NUMROWS; 
    end; 
end PKG_ROWCOUNT; 
/

第一個觸發器初始化變量:

create or replace trigger CUSTOMER_CHANGES_TRIGGER_1 
    before insert or update or delete 
    on CUSTOMERS 
begin 
    PKG_ROWCOUNT.INIT_ROWCOUNT; 
end; 

第二每行更新:

create or replace trigger CUSTOMER_CHANGES_TRIGGER_2 
    after insert or update or delete 
    on CUSTOMERS 
    for each row 
begin 
    PKG_ROWCOUNT.ADD_ONE; 
end; 
/

第三個顯示總數:

create or replace trigger CUSTOMER_CHANGES_TRIGGER_3 
    after insert or update or delete 
    on CUSTOMERS 
begin 
    Dbms_output. 
    PUT_LINE(PKG_ROWCOUNT.GET_ROWCOUNT || ' rows were affected.'); 
end; 
+0

非常棒 - 非常感謝您的幫助! – dav83 2012-01-07 17:43:45

+1

在語句重新啓動的情況下,這可能會導致錯誤的結果。如果行觸發器是一個觸發器之前,我會知道這是一個問題。作爲一個觸發後,我不知道重新啓動是否有可能。有關語句重新啓動的更多信息,請參閱:http://tkyte.blogspot.com/search?q=statement+restart – 2012-01-08 22:56:06

+0

自從引入了**複合觸發器**的Oracle 11g以來,現在做起來要容易得多。在before語句中初始化一個rowCount變量。在每個行部分中,增加該變量。在聲明部分之後,您可以訪問該值。所以你不需要3個觸發器,所有的邏輯都可以存在於一個複合觸發器中。 – mancini0 2017-02-23 19:25:01

0

我不是100 $知道這是否是可用的內部AFTER觸發的身體,但你可以嘗試檢查sql%rowcount

+0

謝謝 - 我試過這個,但唉,它只是NULL。 – dav83 2012-01-07 15:12:48