2015-11-01 126 views
0

考慮下表行級觸發器:Insert語句計時問題

create table testtable 
(
id number(10), 
batch_id number(10), 
seq number(10) 
) 

的插入後,行級觸發器對這個表,執行以下操作存在:

create or replace trigger tr_testtable after insert on testtable 
for each row 

pragma autonomous_transaction 

begin 

v_min_seq number(10); 
v_min_id number(10); 
v_batch_id number(10); 
v_count number(5); 

select count(*) into v_count,batch_id into v_batch_id 
from testtable 
where batch_id = :new.batch_id 
group by batch_id; 

if (v_count > 1) then 


with cte(min_seq,batch_id) as 
(
select min(seq),batch_id from testtable 
group by batch_id 
) 
select id into v_min_id from 
testtable tt 
inner join 
cte 
on cte.min_seq = tt.seq 
and cte.batch_id = tt.batch_id; 

delete from testtable 
where id <> v_min_id 
and batch_id = v_batch_id; 

commit; 

end if; 

end; 

下面的INSERT語句運行:

insert into testtable 
select 10, 100, 18 from dual; 
commit; 

insert into testtable 
select 11, 100, 32 from dual; 
commit; 

insert into testtable 
select 12, 100, 15 from dual; 
commit; 

因此,如果上面的Insert語句運行,預期的輸出觸發器被觸發後:

Id Batch_Id Seq 
12 100  15 

現在,這些插入語句在同一時間發射。 我想知道是否有可能所有Insert語句同時執行,並且觸發器觸發時未滿足條件if (v_count > 1)?如果是的話,輸出將是下面的,這是不可取的:

Id Batch_Id Seq 

10 100  18 
11 100  32 
12 100  15 
+2

您的代碼不會給你希望,因爲觸發一個自治事務中運行,不會看到該行作爲輸出插入,因此它只能處理表中以前的數據。它也可能會妨礙回滾。這聽起來像一個[XY問題](http://meta.stackexchange.com/a/66378/150299)。你究竟在做什麼*試圖在這裏實現? –

+0

我想要達到的是 - 在批處理(BatchId)中,保存包含最小序列(Seq)的記錄並刪除其他記錄。 – youfree

+0

是否有可能收到兩個不同ID的記錄,但綁最小的SEQ?如果是這樣,你想發生什麼?你是否想保持最小SEQ的記錄ID? – APC

回答

1

如果您需要管理重複的記錄,讓我們嘗試另一種方式。 MERGE statement是你可以指定條件的方式來決定是否更新或插入到目標表

MERGE INTO testtable t1 
USING (select 10 as id, 100 as batch_id, 18 as seq from dual) t2 
ON (t1.batch_id = t2.batch_id) 
WHEN MATCHED THEN 
    UPDATE SET t1.seq = t2.seq 
    WHERE t1.seq > t2.seq 
WHEN NOT MATCHED THEN 
    INSERT (id, batch_id, seq) 
    VALUES (t2.id,t2.batch_id, t2.seq); 

MERGE INTO testtable t1 
USING (select 11 as id, 100 as batch_id, 32 as seq from dual) t2 
ON (t1.batch_id = t2.batch_id) 
WHEN MATCHED THEN 
    UPDATE SET t1.seq = t2.seq 
    WHERE t1.seq > t2.seq 
WHEN NOT MATCHED THEN 
    INSERT (id, batch_id, seq) 
    VALUES (t2.id,t2.batch_id, t2.seq); 

MERGE INTO testtable t1 
USING (select 12 as id, 100 as batch_id, 15 as seq from dual) t2 
ON (t1.batch_id = t2.batch_id) 
WHEN MATCHED THEN 
    UPDATE SET t1.seq = t2.seq 
    WHERE t1.seq > t2.seq 
WHEN NOT MATCHED THEN 
    INSERT (id, batch_id, seq) 
    VALUES (t2.id,t2.batch_id, t2.seq); 
+0

該解決方案爲OP帖子中的ID生成不同的值。這可能也可能不重要,這取決於OP希望實施的具體業務規則。 – APC