Oracle PL / SQL: пересылка всей строки в процедуру из триггера - PullRequest
8 голосов
/ 21 июня 2011

In имеет триггер уровня строки Oracle / 10i / PL / SQL, который отвечает за три независимых задачи.Поскольку триггер в этом случае относительно беспорядочный, я хочу экспортировать эти три задачи в три хранимые процедуры.Я думал об использовании параметра my_table%ROWTYPE или, возможно, типа коллекции для процедур, но моя главная задача - как заполнить эти параметры.

Есть ли способ поместить всю строку :NEWлегко вызвать одну переменную?До сих пор единственный способ, которым я мог узнать, - это назначать каждое поле отдельно для переменной, которая не совсем удовлетворительна, смотреть на ведение кода и т. Д.

Что-то вроде

SELECT :NEW.* INTO <variable> FROM dual;

будет предпочтительным.(Я на самом деле не пробовал, но полагаю, это не сработает)

Ответы [ 4 ]

8 голосов
/ 21 июня 2011

В подавляющем большинстве случаев единственным способом присвоения новых значений в строке переменной% ROWTYPE было бы явное назначение каждого столбца. Что-то вроде

CREATE OR REPLACE TRIGGER some_trigger_name
  BEFORE INSERT OR UPDATE ON some_table
  FOR EACH ROW
DECLARE
  l_row some_table%rowtype;
BEGIN
  l_row.column1 := :NEW.column1;
  l_row.column2 := :NEW.column2;
  ...
  l_row.columnN := :NEW.columnN;

  procedure1( l_row );
  procedure2( l_row );
  procedure3( l_row );
END;

Если ваша таблица объявлена ​​на основе объекта, то: NEW будет объектом этого типа. Так что если у вас есть стол, как

CREATE OR REPLACE TYPE obj_foo 
    AS OBJECT (
      column1 NUMBER,
      column2 NUMBER,
      ...
      columnN NUMBER );

CREATE TABLE foo OF obj_foo;

тогда вы можете объявить процедуры, которые принимают входные параметры типа OBJ_FOO, и вызывать их непосредственно из вашего триггера.

Предложение в другом потоке о выборе строки из таблицы в потоке AFTER INSERT / UPDATE, к сожалению, обычно не работает. Как правило, это приводит к исключению из таблицы мутаций.

  1  create table foo (
  2    col1 number,
  3    col2 number
  4* )
SQL> /

Table created.

SQL> create procedure foo_proc( p_foo in foo%rowtype )
  2  as
  3  begin
  4    dbms_output.put_line( 'In foo_proc' );
  5  end;
  6  /

Procedure created.

SQL> create or replace trigger trg_foo
  2    after insert or update on foo
  3    for each row
  4  declare
  5    l_row foo%rowtype;
  6  begin
  7    select *
  8      into l_row
  9      from foo
 10     where col1 = :new.col1;
 11    foo_proc( l_row );
 12  end;
 13  /

Trigger created.

SQL> insert into foo values( 1, 2 );
insert into foo values( 1, 2 )
            *
ERROR at line 1:
ORA-04091: table SCOTT.FOO is mutating, trigger/function may not see it
ORA-06512: at "SCOTT.TRG_FOO", line 4
ORA-04088: error during execution of trigger 'SCOTT.TRG_FOO'
3 голосов
/ 21 июня 2011

Это невозможно.

Может быть мой ответ на другой вопрос может помочь.

2 голосов
/ 22 сентября 2011

Используйте SQL для генерации SQL;

select ' row_field.'||COLUMN_NAME||' := :new.'||COLUMN_NAME||';'  from 
     ALL_TAB_COLUMNS cols 
where 
     cols.TABLE_NAME = 'yourTableName'
order by cols.column_name

Затем скопируйте и вставьте вывод.

0 голосов
/ 05 сентября 2011

Это похоже на решение Джастина, но немного короче (без ввода левой части каждого задания):

-- use instead of the assignments in Justins example:
select :new.column1, 
       :new.column2,
...
       :new.columnN,
into l_row from dual;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...