在Oracle数据库中更改触发器的分配

时间:2019-02-11 10:25:07

标签: oracle triggers ddl alter

当我想在Oracle数据库中的现有表中插入一列(或减小字段的大小)时,我将其重命名,重新创建另一个表(使用旧名称)并将数据从旧表复制到新表

但是,与此同时,附加在表格上的所有触发器都根据其新名称而改变,我必须:

  1. 复制一个触发器的定义
  2. 删除此触发器
  3. 在触发器的定义中更改附加表的名称
  4. 重新创建触发器
  5. 对所有附加的触发器执行相同的操作

有什么方法可以更改触发器所引用的表的名称,而不必从头开始重新创建它们?

@Littlefoot
一个例子:

SQL> create table test (id number, name varchar2(20));
Table créée.

SQL> create or replace trigger trg_bi_test
  2    before insert on test
  3    for each row
  4    begin
  5      :new.id := seq_test.nextval;
  6    end;
  7  /
Déclencheur créé.

SQL> insert into test (name) values ('Littlefoot');
1 ligne créée.

SQL> alter table test rename to tmp_test;
Table modifiée.

SQL> create table test (id number, name varchar2(10));
Table créée.

SQL> insert into test
  2  (select id, substr(name, 10) from tmp_test);
1 ligne créée.

SQL> create or replace TRIGGER trg_bi_test
  2    before insert on "TEST"
  3    for each row
  4    begin
  5      :new.id := seq_test.nextval;
  6    end;
  7  /
create or replace TRIGGER trg_bi_test
                          *
ERREUR à la ligne 1 :
ORA-04095: déclencheur 'TRG_BI_TEST' existe déjà sur une autre table,
imposs. de le remplacer

`

触发器的主体是:

create or replace TRIGGER trg_bi_test
  before insert on "TMP_TEST"
  for each row
  begin
    :new.id := seq_test.nextval;
  end;

如您所见,触发器已附加到 TMP_TEST 表,因此,我无法“创建或替换”它。

如果您接受更改工作表的名称,则您的示例是正确的...

1 个答案:

答案 0 :(得分:0)

在列级别上如何做?

例如:

SQL> create table test (id number, name varchar2(20));

Table created.

SQL> create or replace trigger trg_bi_test
  2    before insert on test
  3    for each row
  4  begin
  5    :new.id := seq_test.nextval;
  6  end;
  7  /

Trigger created.

SQL> insert into test (name) values ('Littlefoot');

1 row created.

SQL> select * from test;

        ID NAME
---------- --------------------
        21 Littlefoot

SQL>

添加新列很容易:

SQL> alter table test add (address varchar2(20));

Table altered.

减少的列名称为 tricky 。这个作品;触发器仍然可以:

SQL> alter table test modify name varchar2(15);

Table altered.

SQL> select status from user_triggers where trigger_name = 'TRG_BI_TEST';

STATUS
--------
ENABLED

这不是那么容易,但是-存在一种解决方法:

SQL> alter table test modify id number(4);
alter table test modify id number(4)
                        *
ERROR at line 1:
ORA-01440: column to be modified must be empty to decrease precision or scale


SQL> -- OK; it failed, so - let's add a new column, put old values in there, 
SQL> -- drop the old column, rename the new column:
SQL> alter table test add id_new number(4);

Table altered.

SQL> update test set id_new = id;

1 row updated.

SQL> alter table test drop column id;

Table altered.

SQL> alter table test rename column id_new to id;

Table altered.

SQL> select status from user_triggers where trigger_name = 'TRG_BI_TEST';

STATUS
--------
ENABLED

SQL> insert into test (name) values ('Bigfoot');

1 row created.

SQL> select * from test;

NAME            ADDRESS                      ID
--------------- -------------------- ----------
Littlefoot                                   21
Bigfoot                                      22

SQL>

好,让我们重命名表:

SQL> rename test to test_new;

Table renamed.

SQL> insert into test_new (name) values ('Testing');

1 row created.

SQL> select * from test_new;

NAME            ADDRESS                      ID
--------------- -------------------- ----------
Littlefoot                                   21
Testing                                      23
Bigfoot                                      22

SQL>

如您所见,无论做什么,我都不必触摸扳机。

如果仍然有问题,可以编辑您的消息并演示您的工作以及Oracle的响应方式吗?