2
我有可運行的代碼,下面只是打印消息,並且對我很感興趣。我沒有任何其他與此表相關的觸發器(我做了一個下拉表來強化它),但是當第一次觸發複合觸發器(首次插入表格)時,會發生以下行爲:複合觸發器在第一次插入時的行爲與第一次插入時的行爲不同
- 試驗1)的BEFORE語句運行兩次第一插入但只是一次之後
BEFORE語句數量:0 BEFORE語句數量:0
- 測試2)變量qty對於第一次插入具有NULL值,之後具有期望值。
語句後數量:
你可以解釋這種現象?
SET SERVEROUTPUT ON;
--DROP TABLE teste_var_global;
CREATE TABLE teste_var_global(
idVal NUMBER
);
create or replace TRIGGER compounder
FOR UPDATE OR INSERT OR DELETE ON teste_var_global
COMPOUND TRIGGER
qty NUMBER;
BEFORE STATEMENT IS
BEGIN
SELECT COUNT(*) INTO qty FROM teste_var_global;
DBMS_OUTPUT.PUT_LINE('BEFORE STATEMENT IS');
DBMS_OUTPUT.PUT_LINE('Qty: ' || qty);
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('(' || SQLCODE || ') - ' || SQLERRM);
END BEFORE STATEMENT;
BEFORE EACH ROW IS
BEGIN
DBMS_OUTPUT.PUT_LINE(CHR(9)||'BEFORE EACH ROW IS');
IF INSERTING THEN
DBMS_OUTPUT.PUT_LINE(CHR(9)||':new.idVal ' || :new.idVal);
ELSIF DELETING THEN
DBMS_OUTPUT.PUT_LINE(CHR(9)||':old.idVal ' || :old.idVal);
ELSE --UPDATING
DBMS_OUTPUT.PUT_LINE(CHR(9)||':old.idVal ' || :old.idVal);
DBMS_OUTPUT.PUT_LINE(CHR(9)||':new.idVal ' || :new.idVal);
END IF;
END BEFORE EACH ROW;
AFTER EACH ROW IS
BEGIN
DBMS_OUTPUT.PUT_LINE(CHR(9)||'AFTER EACH ROW IS');
IF INSERTING THEN
DBMS_OUTPUT.PUT_LINE(CHR(9)||':new.idVal ' || :new.idVal);
DBMS_OUTPUT.NEW_LINE();
qty:= qty + 1; -- increment
ELSIF DELETING THEN
DBMS_OUTPUT.PUT_LINE(CHR(9)||':old.idVal ' || :old.idVal);
DBMS_OUTPUT.NEW_LINE();
qty:= qty -1; -- decrement
ELSE --UPDATING
DBMS_OUTPUT.PUT_LINE(CHR(9)||':old.idVal ' || :old.idVal);
DBMS_OUTPUT.PUT_LINE(CHR(9)||':new.idVal ' || :new.idVal);
DBMS_OUTPUT.NEW_LINE();
END IF;
END AFTER EACH ROW;
AFTER STATEMENT IS
BEGIN
DBMS_OUTPUT.PUT_LINE('AFTER STATEMENT IS');
DBMS_OUTPUT.PUT_LINE('Qty: ' || qty);
DBMS_OUTPUT.NEW_LINE();
END AFTER STATEMENT;
END;
/
-- Test 1, will fire BEFORE STATMENT twice when the first row is inserted
INSERT INTO teste_var_global
(
SELECT 1 FROM DUAL
UNION ALL
SELECT 2 FROM DUAL
UNION ALL
SELECT 3 FROM DUAL
)
/
--Test 2, qty will become NULL when this trigger is fired for the first time
--drop the table and rerun the trigger before executing this command
INSERT INTO teste_var_global VALUES(1);
/
因爲Oracle確保觸發器在最後一次**被觸發**,但不能保證它在多用戶環境中被激發**一次**,請參閱此鏈接:https://asktom.oracle .com/pls/asktom/f?p = 100:11:0 :::: P11_QUESTION_ID:2599480800346313755 – krokodilko
@krokodilko這是非常好的解釋。 – Kacper