如何创建在表中完成任何插入或更新时触发的触发器?

时间:2016-06-23 05:37:25

标签: oracle plsql oracle10g

我已经创建了下面的触发器,但是在我对所提到的表进行新的插入/更新后它没有被触发:

UILocalNotification

有人可以告诉我我错过了什么吗?

3 个答案:

答案 0 :(得分:1)

正如@phonetic_man所指出的,你隐藏了通过捕获when others并且不采取任何行动而获得的任何错误。如果没有异常块,您将看到导致变异表错误(ORA-04091),因为您指的是触发器所针对的同一个表。

如果您取出for each row部分将其转换为语句级触发器,那么您将避免该问题,但现在您将有一个无限循环(ORA-00036) - 当您尝试更新触发器内的表,更新本身会导致同一触发器再次触发;它试图再次更新同一个表,这会导致触发器再次触发;等,直到Oracle注意到并终止了这个过程。

使用插入前的行级触发器来确保行的新值与您尝试强制执行的任何模式匹配更有意义。也许是这样的:

CREATE OR REPLACE TRIGGER ref_upd_user_phi_details
BEFORE INSERT OR UPDATE --of emp_email_address, ssn_nb 
ON ref_adp_employees
REFERENCING OLD AS OLD NEW AS NEW
FOR EACH ROW 
BEGIN
    IF upper(:NEW.emp_email_address) NOT LIKE 'QA_%'
      AND upper(:NEW.emp_email_address) LIKE '%@KEENAN.COM'
    THEN
      :NEW.emp_email_address := 'QA_' || :NEW.emp_email_address;
      :NEW.ssn_nb := CASE WHEN :NEW.ssn_nb IS NULL THEN  '123-45-6789' END;
    END IF;
END;
/

看看它的作用:

insert into ref_adp_employees (emp_id, emp_email_address, ssn_nb) values (1, 'TEST_1', '123-45-6789');
insert into ref_adp_employees (emp_id, emp_email_address, ssn_nb) values (2, 'TEST_1@KEENAN.COM', '123-45-9876');
insert into ref_adp_employees (emp_id, emp_email_address, ssn_nb) values (3, 'QA_TEST_1', null);

select emp_id, emp_email_address, ssn_nb from ref_adp_employees;

    EMP_ID EMP_EMAIL_ADDRESS              SSN_NB    
---------- ------------------------------ -----------
         1 TEST_1                         123-45-6789
         2 QA_TEST_1@KEENAN.COM                      
         3 QA_TEST_1                                 

不确定您是否真的打算将set SSN替换为null,并将空值转换为固定值;我怀疑你真的试图用固定字符串替换设置值并单独留下空值,在这种情况下它将是:

      :NEW.ssn_nb := CASE WHEN :NEW.ssn_nb IS NOT NULL THEN  '123-45-6789' END;

您可能还希望将其移到IF块之外,以便完成,无论电子邮件地址如何;我已经复制了原始代码尝试做的事情,但这可能不对。

如果您要修改现有数据以匹配这些更改,请对整个表格进行一次性更新 - 不要尝试在触发器内执行此操作。

答案 1 :(得分:0)

你听说过谷歌吗?触发器有无数的答案和例子,但我现在看到的一些事情:

1)将触发器更改为插入或更新之前。在更改另一个表时使用AFTER,或在表上运行一些后续过程。

2)将注释取出到要更改或添加的各个字段。这是一个很好的AFAIK。

3)在您的触发器体内使用“插入”和“更新时”。或者,如果您只是更新表,请仅将DDL更改为BEFORE UPDATE。

4)在更新中,引用set:new.emp_email_address ='QA_'|| :old.emp_email_address ......依此类推。这就像旧的和新的一样变得重要。

答案 2 :(得分:0)

请通过触发以下查询来检查触发器是否有效..

SELECT *
FROM   ALL_OBJECTS
WHERE  OBJECT_NAME = trigger_name
AND    OBJECT_TYPE = 'TRIGGER'
AND    STATUS <> 'VALID'

触发器在更新后触发.. 在更新前尝试

CREATE OR REPLACE TRIGGER ref_upd_user_phi_details
Before
INSERT OR UPDATE