我正在嘗試創建一個觸發器,以在插入到另一個表中時自動生成和插入帶有年和月 (YYYYMM) 的值到表中。
示例:當插入表 'original_table'
create table original_table
(opt_value char(2),
low_value varchar2(24),
high_value varchar2(24));
create table new_values
(id_values varchar2(24),
yr_month number(6));
Insert into original_table(opt_value,low_value,high_value) values ('EQ', '1111111111', '1111111111');
Insert into original_table(opt_value,low_value,high_value) values ('BT', '2222222000', '2222222999');
Insert into original_table(opt_value,low_value,high_value) values ('BT', '3333333350', '3333333399');
原始表
| 選擇值 | 低價值 | 高價值 |
|---|---|---|
| 情商 | 1111111111 | 1111111111 |
| BT | 2222222000 | 2222222999 |
| BT | 3333333350 | 3333333399 |
Obs:EQ 代表“平等”,BT 代表“介于”。當 'EQ' 只需要插入低或高值之一無關緊要時,當 'BT' 需要生成兩個值之間的所有數字并插入然后插入到 'new_values' 表中時。
表 'new_values' 應該得到:
新值
| id_values | 年月 |
|---|---|
| 1111111111 | 202111 |
| 2222222000 | 202111 |
| 2222222001 | 202111 |
| 2222222002 | 202111 |
| ... | ... |
| 2222222999 | 202111 |
| 3333333350 | 202111 |
| 3333333351 | 202111 |
| ... | ... |
| 3333333399 | 202111 |
我創建了一個有效的觸發器,但我發現它有點慢,而且我不喜歡使用 BEFORE INSERT 陳述句,但不能使用 AFTER INSERT 而不會出現變異表錯誤。
create or replace TRIGGER TRG_NAME
BEFORE INSERT
ON original_table
FOR EACH ROW
BEGIN
IF :NEW.opt_value = 'BT' THEN
INSERT INTO new_values (id_values, yr_month)
with tab123 (h_value, l_value, y_month)
as (select :NEW.high_value, cast(:NEW.low_value as number) , to_char(trunc(sysdate), 'YYYYMM')
from original_table
union all
select h_value, l_value 1, y_month
from tab123
where l_value < h_value)
select distinct l_value, y_month
from tab123;
ELSIF :NEW.opt_value = 'EQ' THEN
INSERT INTO new_values (id_values, yr_month) values
( :NEW.high_value, to_char(add_months(trunc(sysdate), -1), 'YYYYMM'));
END IF;
END;
任何有關如何改進此代碼的提示將不勝感激。
uj5u.com熱心網友回復:
當您從正在更改的表中讀取時,您會收到一個變異表錯誤。
奇怪的是,您是在 AFTER INSERT 觸發器中而不是在 BEFORE INSERT 觸發器中獲取它。我會假設它們都會導致相同的錯誤,因為在這兩種情況下,您都從觸發器的觸發表中讀取資料。嗯,這可能與只插入一行有關。如果您一次插入更多行,您可能會收到兩個觸發器變體的錯誤。
在您的情況下,讀取觸發器中 original_table 中的所有行只會產生重復項,而您使用DISTINCT. 相反,不要從表中讀取。這不是必要的。DUAL改為讀取,以獲得具有所需值的一行:
with tab123 (h_value, l_value, y_month) as
(
select :new.high_value, cast(:new.low_value as number), to_char(sysdate, 'yyyymm')
from dual
union all
select h_value, l_value 1, y_month
from tab123
where l_value < h_value
)
select l_value, y_month
from tab123;
這將使您擺脫變異表錯誤并加速觸發器。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/367888.html
