我有下面的可运行代码,它只是打印消息并且让我很感兴趣。我没有任何与此表相关的其他触发器(我使用drop table来强化它),但是当第一次触发复合触发器(第一次插入表)时,会发生以下行为:
在声明之前是数量:0在声明之前是数量:0
报表后数量:
你能解释一下这种行为吗?
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);
/
答案 0 :(得分:0)
当我创建表并触发时,这就是我的数据库上的输出效果。
BEFORE STATEMENT IS
Qty: 0
BEFORE EACH ROW IS
:new.idVal 1
AFTER EACH ROW IS
:new.idVal 1
BEFORE EACH ROW IS
:new.idVal 2
AFTER EACH ROW IS
:new.idVal 2
BEFORE EACH ROW IS
:new.idVal 3
AFTER EACH ROW IS
:new.idVal 3
AFTER STATEMENT IS
Qty: 3
第二个测试用例给出:
BEFORE STATEMENT IS
Qty: 0
BEFORE EACH ROW IS
:new.idVal 1
AFTER EACH ROW IS
:new.idVal 1
AFTER STATEMENT IS
Qty: 1
但请在下面的评论中查看krokodilko发布的链接。