【问题标题】: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 应该如何知道您要删除它?

标签: sql oracle oracle11g oracle-xe


【解决方案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。感谢您的努力和好评。赞赏!!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多