【问题标题】:Trigger to select all columns except one?触发选择除一列之外的所有列?
【发布时间】:2013-12-19 10:22:08
【问题描述】:

一旦在 main 中修改日期列,下面的触发器会将除 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;

【问题讨论】:

  • 否; related but not quite duplicate question。您可以在每次更改后从表定义中生成触发器创建脚本,但仍然必须以某种方式重新创建它,并使用明确列出的新列。

标签: sql oracle triggers


【解决方案1】:

我将为您提供一种可以引导您找到解决方案的方法。这段代码真的没有测试,因为我现在没有时间做,但我希望它可以帮助你......

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;

在那里您可以获得表 HINT 的所有当前列,当然,这些列会考虑您所做的任何更改表。

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);

希望对你有帮助……

【讨论】:

  • 请注意,即使可以在触发器中声明和执行动态语句,这通常也是一个非常糟糕的主意,尤其是对于诸如主/历史表触发器之类的东西:开销太大/执行时间太长。您可以也许通过检查表是否为ALTERed 并将语句存储在外部表中来优化它...但此时您也可以只运行脚本以“永久”重新生成触发器。
猜你喜欢
  • 2013-03-23
  • 2018-12-16
  • 2020-12-17
  • 1970-01-01
  • 1970-01-01
  • 2018-11-23
  • 1970-01-01
  • 2013-01-01
  • 1970-01-01
相关资源
最近更新 更多