【问题标题】:use the same auto increment trigger in oracle for many tables在 oracle 中对许多表使用相同的自动增量触发器
【发布时间】:2016-05-30 03:48:55
【问题描述】:

我在 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,所以没有标识列

提前致谢

我打算只对我提到的第一篇帖子发表评论,但如果没有更多声望点,我无法发表评论:/

【问题讨论】:

    标签: oracle triggers auto-increment


    【解决方案1】:

    无法在 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;
    

    【讨论】:

    • 这很有趣,以前从未使用过 PL/SQL。我需要安装一些驱动程序或其他东西才能使用它吗?另外我不明白table_nameuser_tables 在这部分是什么:for i in (select table_name from user_tables
    • 您好,PL/SQL 是 ORACLE 数据库的标准部分。 USER_TABLES 是字典视图的一部分,其中包含 DB docs.oracle.com/cd/B28359_01/server.111/b28310/tables014.htm 的元数据
    猜你喜欢
    • 2012-04-17
    • 1970-01-01
    • 2010-09-23
    • 2013-04-29
    • 2015-11-11
    • 2020-05-09
    • 2015-06-09
    • 2011-12-06
    相关资源
    最近更新 更多