在Oracle(11.2.0.1),我有2個表,假設觸發一個和乙與他們之間的借鑑約束( 「ON DELETE CASCADE」) 。 A是B的「父」。的Oracle 11g:化合物與 「ON DELETE CASCADE」 約束
create table A (id number(9) not null primary key);
create table B (id number(9) not null primary key, parent_id not null references A(id) on delete cascade);
子表也有從中刪除相關化合物觸發(主要目的是爲了避免在一系列複雜的完整性檢查突變的錯誤)。
create or replace trigger trg_b
for delete on b
compound trigger
type b_table is table of b%rowtype;
b_collection b_table := b_table();
before each row is
begin
b_collection.extend;
b_collection(b_collection.last).id := :old.id;
b_collection(b_collection.last).parent_id := :old.parent_id;
end before each row;
after statement is
begin
for i in b_collection.first .. b_collection.last loop
--logging into another table in an autonomous transaction
end loop;
b_collection.delete;
end after statement;
end trg_b;
之一算法這些表的工作是以下幾點:
- 與特定PARENT_ID所有行將從乙被刪除。如果沒有子行留下
- 額外的檢查。
- 從父母刪除此特定ID A。
在我們的生產環境中,第3步在字符串b_collection.first .. b_collection.last
處生成異常ORA-06502: PL/SQL: numeric or value error
。這意味着從父表中刪除導致觸發子表上的觸發器,即使沒有可能的子行受到影響。這可能是有道理的,因爲觸發器被觸發並且第一個和最後一個收集索引爲NULL時,集合不存在,但是我不能再現這種行爲。
在我們的開發環境中,當我試圖從B中刪除一些不存在的id/parent_id時,我只能得到ORA-06502
。在它轉彎時,我嘗試刪除一些存在的(無子行)或不存在的ID從一個我沒有得到任何錯誤 - 0行刪除,0影響子行。從日誌記錄我可以告訴孩子相關的觸發器甚至在這種情況下不被解僱。爲什麼不?
任何想法,爲什麼所描述的行爲可能會如此不同?我錯過了什麼?
感謝您的快速回復!我知道如何正確處理空集合,但真正困擾我的是帶觸發器的魔法。 – Ennike