Oracle PL / SQL: динамическое циклическое переключение по столбцам триггера - PullRequest
4 голосов
/ 24 апреля 2009

Внутри триггера я пытаюсь перебрать все столбцы в таблице и сравнить новые значения со старыми значениями. Вот что у меня есть:

CREATE OR REPLACE TRIGGER "JOSH".TEST#UPD BEFORE 
UPDATE ON "JOSH"."TEST_TRIGGER_TABLE" REFERENCING OLD AS OLD NEW AS NEW FOR EACH ROW
declare    
   oldval varchar(2000);   
   newval varchar(2000);   
begin    
   for row in (SELECT column_name from user_tab_columns where table_name='TEST_TRIGGER_TABLE') loop  
     execute immediate 'select :old.'||row.column_name||' from dual'   into oldval;  
     execute immediate 'select :new.'||row.column_name||' from dual'   into newval;  
     --Do something here with the old and new values
   end loop;  
end;

Триггер компилируется, но когда срабатывает триггер, я получаю:

ORA-01008: не все переменные связаны

при первом выполнении немедленно, потому что он ожидает значение для :old. :old и :new уже определены как часть триггера, но, по-видимому, немедленно выполнить не может увидеть эти переменные.

Есть ли способ динамически перебирать значения столбцов в триггере?

Ответы [ 4 ]

5 голосов
/ 24 апреля 2009

Нет, вы не можете ссылаться на: старые и: новые значения динамически. Как предполагает Шейн, вы можете написать код для генерации статического кода триггера, если это облегчает жизнь. Кроме того, вы можете превратить «что-то здесь» в процедуру пакета, чтобы ваш триггер стал:

CREATE OR REPLACE TRIGGER JOSH.TEST#UPD BEFORE 
UPDATE ON JOSH.TEST_TRIGGER_TABLE
begin    
   my_package.do_something_with (:old.col1, :new.col1);
   my_package.do_something_with (:old.col2, :new.col2);
   my_package.do_something_with (:old.col3, :new.col3);
   -- etc.
end;

(Кстати, вы можете отказаться от бессмысленного предложения ССЫЛКА).

4 голосов
/ 24 апреля 2009

Вы по сути пытаетесь построить свою собственную систему для аудита всех изменений в таблице? (Моя лучшая догадка относительно того, что вы могли бы делать со старыми и новыми значениями произвольных столбцов.) Если это так, вы, возможно, захотите изучить собственные возможности аудита Oracle.

4 голосов
/ 24 апреля 2009

Я не уверен, что вы можете делать то, что пытаетесь сделать. По какой причине вы не хотите явно называть столбцы таблицы внутри кода PL / SQL? Если поля таблицы часто меняются, вы можете создать PL / SQL, который динамически создает триггер PL / SQL для каждой таблицы (с явными именами полей в каждой). Каждый раз, когда таблица изменяется, вы можете запустить этот PL / SQL для генерации нового триггера.

2 голосов
/ 24 апреля 2009

У меня была похожая проблема, хотя в MSSQL.

Мое решение состояло в том, чтобы написать хранимую процедуру, которая перебирает информацию о таблицах и столбцах (либо через представления словаря, либо через пользовательский репозиторий) и генерирует необходимые триггеры. Процедуру необходимо запускать только в случае изменения модели данных.

Преимущество заключается в том, что вам не нужно перемещаться по метамодели в каждом обновлении, а скорее генерировать свои триггеры заранее.

...