oracle - 一个表字段上的触发器适用于所有表字段

标签 oracle plsql oracle11g plsqldeveloper

我有一个用于表中几个字段的触发器。但由于某种原因,如果另一个字段发生更改(触发器中未定义),那么它仍然会触发。

CREATE OR REPLACE TRIGGER INTEGRATION_EMPLOYMENT
    AFTER UPDATE OF start_day_of_employment, end_of_employment ON hr_employment_data
    FOR EACH ROW
    DECLARE
    BEGIN
         IF UPDATING THEN
            MERGE INTO ad_integration intg USING dual ON (intg.user_id = :NEW.user_id AND intg.integrated = 'NO')
            WHEN MATCHED THEN
                UPDATE SET
                         intg.start_day_of_employment = decode(:NEW.start_day_of_employment, NULL, ' ', :NEW.start_day_of_employment),
                         intg.end_of_employment = decode(:NEW.end_of_employment, NULL, ' ', :NEW.end_of_employment),
                         intg.manager_status = :NEW.manager_status,
                         intg.pid = (SELECT pid FROM arc.user_info WHERE user_id = :NEW.user_id),
                         intg.network_access_start_date = (SELECT network_access_start_date FROM hr_extension_data WHERE user_id = :NEW.user_id)
             WHEN NOT MATCHED THEN
                INSERT (intg.user_id, intg.start_day_of_employment, intg.end_of_employment, intg.manager_status, intg.pid, intg.network_access_start_date
                VALUES (:NEW.user_id, :NEW.start_day_of_employment, :NEW.end_of_employment, :NEW.manager_status, (SELECT pid FROM arc.user_info WHERE user_id = :NEW.user_id), (SELECT network_access_start_date FROM hr_extension_data WHERE user_id = :NEW.user_id));
END IF;

END HR_ADINTEGRATION_EMPLOYMENT;

是因为使用了 DUAL 还是我遗漏了什么?

干杯! :-)

最佳答案

如果您想保持结构不变并且仅在特定字段更改时处理触发器,则只需进行快速比较(新代码第 7 行和第 8 行):

CREATE OR REPLACE TRIGGER INTEGRATION_EMPLOYMENT
AFTER UPDATE OF start_day_of_employment, end_of_employment ON hr_employment_data
FOR EACH ROW
DECLARE
BEGIN
     IF UPDATING 
        AND (:NEW.start_day_of_employment <> :OLD.start_day_of_employment
        OR   :NEW.end_of_employment <> :OLD.end_of_employment)  THEN
        MERGE INTO ad_integration intg USING dual ON (intg.user_id = :NEW.user_id AND intg.integrated = 'NO')
        WHEN MATCHED THEN
            UPDATE SET
                     intg.start_day_of_employment = decode(:NEW.start_day_of_employment, NULL, ' ', :NEW.start_day_of_employment),
                     intg.end_of_employment = decode(:NEW.end_of_employment, NULL, ' ', :NEW.end_of_employment),
                     intg.manager_status = :NEW.manager_status,
                     intg.pid = (SELECT pid FROM arc.user_info WHERE user_id = :NEW.user_id),
                     intg.network_access_start_date = (SELECT network_access_start_date FROM hr_extension_data WHERE user_id = :NEW.user_id)
         WHEN NOT MATCHED THEN
            INSERT (intg.user_id, intg.start_day_of_employment, intg.end_of_employment, intg.manager_status, intg.pid, intg.network_access_start_date
            VALUES (:NEW.user_id, :NEW.start_day_of_employment, :NEW.end_of_employment, :NEW.manager_status, (SELECT pid FROM arc.user_info WHERE user_id = :NEW.user_id), (SELECT network_access_start_date FROM hr_extension_data WHERE user_id = :NEW.user_id));
END IF;

END HR_ADINTEGRATION_EMPLOYMENT;

关于oracle - 一个表字段上的触发器适用于所有表字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11733873/

相关文章:

oracle - 如何使用Delphi/Ado进行带有数组参数的Oracle过程进行批量插入?

sql - 为什么在触发器内部未执行 raise_application_error 之前的代码?

oracle - PL SQL 中的 WHILE 循环有什么问题?

mysql - SQL alter table 在 MySQL 中有效,但在 Oracle 中无效

sql - Oracle 排序依据 - 基于函数 (dense_rank)

java - Hibernate 翻译功能

sql - PLSQL - 字符串中所有字符的计数

database - 将主键从字符串更改为数字的最简单方法

oracle - PostgreSQL 与 Oracle : "compile-time" checking of PL/pgSQL

oracle - 如何将 "GMT+5.5_(INDIA) "转换为时区区域 "Asia/Kolkata"