2013-12-19 58 views
0

下面的觸發器在主表中修改日期列後,將主表中除col1之外的所有列從主表複製到歷史表。 我打算給main和hist添加更多的列,但每次我這樣做的時候,我都不得不修改我的觸發器。有沒有什麼辦法可以讓我的觸發器選擇除col1之外的所有列?觸發器選擇除一個之外的所有列?

CREATE OR REPLACE TRIGGER ins_his BEFORE UPDATE OF datetime ON main 
FOR EACH ROW 
BEGIN 

INSERT INTO hist (col2,col3) VALUES (:new.col2, :new.col3); 

END; 
+1

否; [相關但不完全重複的問題](http://stackoverflow.com/q/9133120/266304)。您可以在每次更改後從表格定義中生成觸發器創建腳本,但仍然必須以某種方式重新創建,並且新列明確列出。 –

回答

0

我會給你一個方法,可能會導致你的解決方案。此代碼是真的不測試,因爲現在我沒有時間去做,但我希望它可以幫助你......

1)創建一個遊標這樣的:

declare v_table_name  varchar2(30) := 'HIST'; 

cursor cur is select column_name, data_type 
       from all_tab_columns 
       where table_name = v_table_name 
       and column_name != 'COL1' 
       order by column_id; 

有你可以得到表格的所有當前列,當然,將考慮你所做的任何變更表。

2)您必須獲取該遊標並創建一個動態插入語句。事情是這樣的:

declare v_column_list  varchar2(500); 
declare v_values_list  varchar2(500); 

for i in cur loop 
    v_column_list := v_column_list||','||i.column_name; 
    v_values_list := v_values_list||', :new.'||i.column_name; 
end loop; 

3)創建動態插入語句並執行:

declare csql    varchar2(500); 

csql := 'INSERT INTO '||v_table_name||' ('||v_column_list||') VALUES ('||v_values_list||')'; 

EXECUTE IMMEDIATE (csql); 

希望這有助於...

+0

請注意,即使可以在觸發器中聲明和執行動態語句,通常也是一個非常糟糕的主意,特別是對於主/歷表觸發器而言:開銷太大/執行時間過長。您可以通過讓它檢查表是否爲'ALTER'ed來優化它,並將該語句存儲在外部表中,但此時您可以運行腳本以「永久」重新生成觸發器。 –

相關問題