我在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所以没有标识列
提前致谢
我只是对我提到的第一篇文章发表评论,但我无法在没有更多声望的情况下发表评论:/
答案 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;