PL / SQL DEVELOPER 10.2创建触发器

时间:2014-08-17 13:15:26

标签: sql oracle plsql

create or replace trigger TDB_TRIGGER1
   before insert on KTOVOT
   for each row
declare
begin
   insert into TEMPORARY_DATA(MIS_ZEHUT,TA_RISHUM, SHEM_TAVLA)
   values(:new.id, sysdate, user_tables.table_name);
end TDB_TRIGGER1

我收到此错误:

PL/SQL: ORA-00984: column not allowed here

我想在这里写的是写入表格:

TEMPORARY_DATA mis_zehut, ta_rishum, user_tables.table_name

我想将表名ktovot写入表TEMPORARY_DATA的第三个字段,但没有成功。

如果我这样做硬编码它将起作用:

values(:new.id, sysdate, 'ktovot' );

1 个答案:

答案 0 :(得分:1)

PL / SQL不支持反射 - 或者说它支持非常有限的反射级别。没有像Java那样的东西。但我们可以使用$$PLSQL_UNIT查询指令找出当前程序单元的名称Find out more

触发器是程序单元,因此我们可以找出当前正在执行的触发器的名称。通过这条信息,我们可以查找拥有触发器的表的名称:

create or replace function get_table_name
    ( i_trigger_name in varchar2)
    return varchar2
is
    return_value varchar2(30);
begin
    select table_name
    into return_value
    from user_triggers
    where trigger_name = i_trigger_name;
    return return_value;
end;
/

所以,这是一个日记表:

create table jrnl1 (id number
                     , action varchar2(20)
                     , ts timestamp
                     , table_name varchar2(30));

这是一个触发器,用于填充该日志,动态获取表名称:

create or replace trigger t23_trg
    before insert on t23 for each row
begin
    insert into jrnl1 values 
        (:new.id
         , 'INSERT'
         , systimestamp
         , get_table_name($$PLSQL_UNIT));
end;
/

以下是布丁的证明:

SQL> select * from jrnl1;

no rows selected

SQL> insert into t23 values ('TEST', 42);

1 row created.

SQL> select * from jrnl1;

        ID ACTION   TS                           TABLE_NAME
---------- -------- ---------------------------- ------------------------------
        42 INSERT   17-AUG-14 10.14.30.688672 AM T23

SQL> 

我担心这不是你可能希望的优雅解决方案。事实上,鉴于你必须为每个表编写一个单独的触发器,我不确定它是否会为硬编码节省很多。

但我认为这是一个有趣的玩具,用于说明PL / SQL的工作原理。