在oracle中为许多表使用相同的自动增量触发器

时间:2016-02-18 05:37:59

标签: oracle triggers auto-increment

我在MySQL中创建了一个包含~10个表的数据库,每个表都以列

开头
SN INT NOT NULL AUTO_INCREMENT 

SN并不代表任何东西,只是区分可能重复/相似名称/标题等的主要内容

我现在将它移到Oracle,并找到this post here on stackoverflow来触发自动递增SN字段。基本上,

CREATE SEQUENCE user_seq;

CREATE OR REPLACE TRIGGER user_inc 
BEFORE INSERT ON users 
FOR EACH ROW

BEGIN
  SELECT user_seq.NEXTVAL
  INTO   :new.SN
  FROM   dual;
END;
/

现在,如何重写该触发器一次以应用于所有其他表?因为否则我必须为许多表重写它,只需更改触发器名称和序列名称......我想象的是:

BEFORE INSERT ON users OR other_table OR another_one

我也找到this post here,但是那里的答案没有用,因为我觉得很多桌子都有相同的SN字段是合理的,或者我误解了点。

另外,不是Oracle 12c所以没有标识列

提前致谢

我只是对我提到的第一篇文章发表评论,但我无法在没有更多声望的情况下发表评论:/

1 个答案:

答案 0 :(得分:2)

创建一个引用Oracle中许多表的触发器是不可能的, 你可以做的是用PL / SQL语句生成触发器。

以下是如何实现此目的的示例

drop table tab_a;
drop table tab_b;
drop table tab_c;

drop sequence seq_tab_a_id;
drop sequence seq_tab_b_id;
drop sequence seq_tab_c_id;

--create test tables 
create table tab_a (SN number, otherfield varchar2(30), date_field date);
create table tab_b (SN number, otherfield varchar2(30), date_field date);
create table tab_c (SN number, otherfield varchar2(30), date_field date);

-- this pl/sql block creates the sequences and the triggers 
declare
  my_seq_create_stmt varchar2(2000);
  my_trigger_create_stmt varchar2(2000);  
begin

  for i in (select table_name
              from user_tables
            -- remember to change this where condition to filter 
            -- the tables that are relevant for you
            where table_name in ('TAB_A', 'TAB_B', 'TAB_C') )loop  <<TableLoop>>

   my_seq_create_stmt := 'CREATE SEQUENCE '||'SEQ_'||i.table_name||'_ID ' 
                         ||CHR(13)||' START WITH 1 INCREMENT BY 1 NOCYCLE ';

   execute immediate my_seq_create_stmt;
   my_trigger_create_stmt := 'CREATE OR REPLACE TRIGGER '||'TRG_'||i.Table_name||'_ID_BI '||' BEFORE INSERT ON '||i.table_name||' FOR EACH ROW '
                    ||CHR(13)||'BEGIN '
                    ||CHR(13)||'  SELECT '||'SEQ_'||i.table_name||'_ID'||'.NEXTVAL '
                    ||CHR(13)||'  INTO   :new.SN '
                    ||CHR(13)||'  FROM   dual; '
                    ||CHR(13)||'END; ';

   execute immediate my_trigger_create_stmt;
 end loop TableLoop;
end;
/

-- test the triggers and the sequences
insert into tab_a (otherfield, date_field) values ('test 1',sysdate);
insert into tab_a (otherfield, date_field) values ('test 2',sysdate); 

commit;


Select * from tab_a;