拥有一个Oracle(10i)PL / SQL行级触发器,它负责三个独立的任务。由于触发器相对混乱,我希望将这三个任务导出到三个存储过程中。
我在考虑使用my_table%ROWTYPE
参数或者可能是程序的集合类型,但我主要关心的是如何填充这些参数。
有没有办法轻松将触发器的整个:NEW
行放入单个变量?
到目前为止,我能找到的唯一方法是将每个字段分别分配给不太令人满意的变量,查看代码维护等。
像
这样的东西SELECT :NEW.* INTO <variable> FROM dual;
将是首选。 (我没有尝试过,但我认为它不起作用)
答案 0 :(得分:8)
在绝大多数情况下,将行中的新值分配给%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'
答案 1 :(得分:3)
这种方式不可能。
也许my answer to another question可以提供帮助。
答案 2 :(得分:2)
使用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
然后复制并粘贴输出。
答案 3 :(得分:0)
这与Justins解决方案类似,但有点短(没有输入每个作业的左侧部分):
-- use instead of the assignments in Justins example:
select :new.column1,
:new.column2,
...
:new.columnN,
into l_row from dual;