Чтобы изменить назначение триггера в базе данных Oracle

Когда я хочу вставить столбец в существующую таблицу (или уменьшить размер поля) в базе данных 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, и из-за этого я не могу его "создать или заменить".

Ваш образец верен, если вы согласны изменить имя рабочего стола...


person Zevet    schedule 11.02.2019    source источник
comment
У вас есть определение триггера в системе управления исходным кодом, верно? Так почему бы просто не применить его к таблице?   -  person eaolson    schedule 12.02.2019
comment
@eaolson Потому что я должен сначала удалить его / их, затем перейти в исходный репозиторий и выполнить скрипт (ы). Каждая таблица имеет 5-6 триггеров и она длинная и источник ошибок...   -  person Zevet    schedule 12.02.2019


Ответы (1)


Как насчет того, чтобы сделать это на уровне столбца?

Например:

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.

Уменьшение имени столбца сложно. Этот работает; триггер все еще в порядке:

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?

person Littlefoot    schedule 11.02.2019
comment
Привет, спасибо, но мой вопрос был не об изменении столбцов в таблице. В вашем примере вы переименовываете старую таблицу в test_new. Что произойдет, если вы захотите сохранить название «тест»? - person Zevet; 11.02.2019
comment
Он сохранялся, пока я его не переименовал. Как я сказал: опубликуйте свой собственный тестовый пример. - person Littlefoot; 11.02.2019
comment
Это нечитабельно, Зевет. Пожалуйста, разместите этот код в вопросе, в исходном сообщении, которое вы написали. - person Littlefoot; 11.02.2019