删除表时是不是可以自动删除触发器和序列

Posted

技术标签:

【中文标题】删除表时是不是可以自动删除触发器和序列【英文标题】:Is it possible to auto drop trigger and sequence when I drop table删除表时是否可以自动删除触发器和序列 【发布时间】:2021-05-29 11:10:45 【问题描述】:

我正在使用 Oracle XE。 当我删除表时,有什么方法可以自动删除触发器和序列? 这是我的表、序列和触发器:

create table country(
country_id number(5) primary key,
country varchar2(36),
country_code varchar2(3)
);

create sequence country_seq
start with 1 increment by 1;

create or replace trigger country_trig
before insert on country
referencing new as new
for each row
begin
select country_seq.nextval into :new.country_id from dual;
end;
/

我在删除主表记录时使用它,然后子表的所有记录都自动删除

【问题讨论】:

删除表时删除表的触发器。使用create sequence 创建的独立序列不与任何表关联,但作为标识列一部分的内部序列会随表一起删除,因此这取决于您的意思。不过,我不确定您的外键示例与该问题有什么关系。 an internal sequence that is part of an identity column is dropped with the table 怎么样?当我删除表并重新创建它并插入记录时,它会从先前创建的序列中获取值 create sequence country_seq * ERROR at line 1: ORA-00955: name is already used by an existing object 我的意思是删除表时不删除序列 序列country_seq 与任何表均无关联。当您删除某个表时,Oracle 应该如何知道您要删除它? 【参考方案1】:

使用create sequence 创建的序列不与任何特定表关联,因此它们永远不会被自动删除。一方面,您可能会为多个表重用一个序列。一个序列属于一个表是没有意义的。

唯一被自动删除的序列是作为identity column 的一部分生成的序列。 (此功能是在 Oracle 12.1 中添加的,当您标记 11g 时,这意味着您没有身份列。)

使用标识列的演示(12.1 及更高版本):

create table demo
( demo_id integer generated always as identity
, some_column varchar2(20) );

create or replace trigger demo_trg
before insert on demo for each row
begin
    dbms_output.put_line('Trigger firing: '||$$plsql_unit);
end demo;
/

现在我有一个带有触发器的表,还有一个与标识列关联的序列:

select * from user_tab_identity_cols where table_name = 'DEMO';
TABLE_NAME COLUMN_NAME GENERATION_TYPE SEQUENCE_NAME IDENTITY_OPTIONS
DEMO DEMO_ID ALWAYS ISEQ$$_88798 START WITH: 1, INCREMENT BY: 1, MAX_VALUE: 9999999999999999999999999999, MIN_VALUE: 1, CYCLE_FLAG: N, CACHE_SIZE: 20, ORDER_FLAG: N, SCALE_FLAG: N, EXTEND_FLAG: N, SESSION_FLAG: N, KEEP_VALUE: N

在这里,序列ISEQ$$_88798 是为我的demo_id 标识列自动创建的。我们也可以在 user_sequences 中看到:

select * from user_sequences where sequence_name = 'ISEQ$$_88798';
SEQUENCE_NAME MIN_VALUE MAX_VALUE INCREMENT_BY CYCLE_FLAG ORDER_FLAG CACHE_SIZE LAST_NUMBER SCALE_FLAG EXTEND_FLAG SHARDED_FLAG
ISEQ$$_88798 1 1E28 1 N N 20 21 N N N

在 user_objects 中:

select o.object_name, o.object_type, o.created
from   user_objects o
where  o.object_name in ('DEMO','DEMO_TRG','ISEQ$$_88798');
OBJECT_NAME OBJECT_TYPE CREATED
DEMO TABLE 27/02/2021 11:09:02
DEMO_TRG TRIGGER 27/02/2021 11:10:42
ISEQ$$_88798 SEQUENCE 27/02/2021 11:09:02

现在,如果我放下桌子,所有三个都会消失:

drop table demo purge;

select o.object_name, o.object_type, o.created
from   user_objects o
where  o.object_name in ('DEMO','DEMO_TRG','ISEQ$$_88798');

no rows selected

如果我创建一个普通序列为create sequence myseq,那么它与表没有关联,所以如果我想删除它,我必须明确地使用drop sequence myseq

【讨论】:

我更新了我的问题并添加了我的表格、序列和触发器。 嗯,简短的回答是,如果您不需要任何序列,您必须自己删除它们。当您删除触发器时,Oracle 不能只删除触发器中引用的所有数据库对象。如果触发器引用了其他表怎么办,它也应该删除它吗?如果您在多个表的多个触发器中使用该序列怎么办? Well, the short answer is that you have to drop any sequences yourself。感谢您的努力和好评。赞赏!!

以上是关于删除表时是不是可以自动删除触发器和序列的主要内容,如果未能解决你的问题,请参考以下文章

sql server 每加一条数据实现自动加一,但怎么实现删除一条数据后自动减一

自动删除连接数据以及删除记录?

mysql怎么自动删除超过3天的数据

我想自动删除嵌入的触发器,我该怎么做?

SQLServer之删除触发器

求一个Oracle触发器 只保存近2天的表中数据,(将之前的数据自动触发删除)。例如对表historyData执行。