【问题标题】:oracle trigger after update on specific field followed by insert更新特定字段后的oracle触发器,然后插入
【发布时间】:2018-03-22 03:20:49
【问题描述】:

我正在创建一个触发器,它将根据更新后和更新中引用的某些文本将记录插入另一个表。

CREATE OR REPLACE TRIGGER NCATSPROD_PM.DEACTIVATE_USERS 
AFTER UPDATE OF "CHANGEBY_CHAR" ON NCATSPROD_PM.PM_USER_DATA 
REFERENCING NEW AS "BICSUPP"
BEGIN
  INSERT INTO NCATSPROD_PM.DEACTIVATED_USERS (USERNAME, EMAIL, DEACTIVATED_DATE) 
     VALUES (SELECT USER_ID, EMAIL, CHANGE_DATE FROM ncatsprod_pm.pm_user_data);
END;

当我尝试编译这个时,我得到一个错误

Error(1,3): PL/SQL: SQL Statement ignored
Error(1,90): PL/SQL: ORA-00936: missing expression

有点不确定我哪里出了问题? Go to source on the error 将我带到 AFTER UPDATE 行,但查看示例我看不到发生了什么。我尝试使用 SQL Developer 的触发器向导,结果相同

【问题讨论】:

  • 首先。您应该在insert 语句中使用values() 子句或select 语句,而不是两者。 values(select) 在语义上不正确。其次。从表中选择在触发器内部定义的触发器将导致mutating table 错误。
  • 您有一个 REFERENCING 子句。这仅对行触发器有效。但是您缺少 FOR EACH ROW 表达式。还有其他错误(正如 Nicholas 指出的那样),但“缺失的表达式”可能是指缺失的 FOR EACH ROW。
  • @NicholasKrasnov - 好的,我刚刚测试过,你是对的:没有 FOR EACH ROW 的 REFERENCING 子句被忽略。 (即使使用了别名,抛出的错误也不同:解析器会抱怨别名,将其视为未知标识符,因为忽略了 REFERENCING 子句。)当然,OP 确实想要一个行触发器,所以会出现其他问题,因为缺少 FOR EACH ROW,但是原始帖子中的错误是由其他原因引起的。
  • 我删除了 VALUES,只是做了 SELECT。那编译得很好。做了一些测试,它没有插入具有 CHANGEBY_CHAR 作为 BICSUPP 的单个记录,而是插入源表中的所有内容。我认为使用引用 new 只会将匹配值 BICSUPP 的记录放入触发器插入中?
  • 你能解释一下... and certain text being referenced in the update.是什么意思吗?

标签: oracle triggers


【解决方案1】:

REFERENCING 子句仅用于更改内置 OLD 和 NEW 记录的名称。 OLD 包含更新前的行的值,NEW 保存更新后的值。下面是一个如何使用它们的示例。

create table PM_USER_DATA (user_id varchar2(20), email varchar2(20), change_date date, changeby_char varchar2(20));
create table DEACTIVATED_USERS (username varchar2(20), email varchar2(20), deactivated_date date);

insert into pm_user_data values ('test', 'test@test.com', sysdate, 'SOMEUSER');

create or replace trigger deactivate_users
    after update of changeby_char on pm_user_data
    referencing old as o1 new as n1
    for each row
begin
    if :n1.changeby_char = 'BICSUPP' then
        insert into deactivated_users (username, email, deactivated_date)
            values (:n1.user_id, :n1.email, :n1.change_date);
    end if;
end;
/

update pm_user_data set changeby_char = 'BICSUPP';

select * from deactivated_users;   
/* output: 
USERNAME             EMAIL                DEACTIVATED_DATE
-------------------- -------------------- ----------------
test                 test@test.com        10-OCT-17       
1 row selected.
*/

【讨论】:

    猜你喜欢
    • 2017-06-26
    • 1970-01-01
    • 2019-07-28
    • 1970-01-01
    • 2021-03-08
    • 2010-12-22
    • 1970-01-01
    • 1970-01-01
    • 2016-10-13
    相关资源
    最近更新 更多