简体   繁体   English

在触发器SQL中更新名称(与以前不同)

[英]Update name (different from previous) in a trigger SQL

I'm writing a trigger for a company database, and this trigger is intended to update a name of an employee (in the rare case of changing name for example) that should be different from a previous one, or NOT NULL. 我正在为公司数据库编写触发器,此触发器旨在更新员工的名称(例如,在极少数情况下更改名称),该名称应与前一个名称不同,或者为NOT NULL。

This is the code I wrote. 这是我写的代码。 It compiles but it gives me error on the update (ORA-04091: table COMPANY.EMPLOYEE is mutating, trigger/function may not see it). 它编译,但它给我更新错误(ORA-04091:表COMPANY.EMPLOYEE正在变异,触发/功能可能看不到它)。 I've noticed that is caused by FOR EACH ROW , but I cannot remove that because otherwise the :new and :old references will not work. 我注意到这是由FOR EACH ROW引起的,但是我无法删除它,因为否则:new:old引用将无效。

CREATE OR REPLACE TRIGGER NO_INVALID_NAME
AFTER UPDATE OF EMPLOYEE_NAME ON EMPLYEE 
FOR EACH ROW
DECLARE
  INVALID_NAME EXCEPTION;
  CORRECT_NAME EXCEPTION;

BEGIN
  UPDATE EMPLOYEE 
  SET EMPLOYEE_NAME =:NEW.EMPLOYEE_NAME
  WHERE EMPLOYEE_NAME =:OLD.EMPLOYEE_NAME;

  IF :NEW.EMPLOYEE_NAME <> :OLD.EMPLOYEE_NAME AND IS NOT NULL THEN
    RAISE INVALID_NAME;
  ELSE
    RAISE CORRECT_NAME;
  END IF;

EXCEPTION
  WHEN NOME_NON_CORRETTO
    THEN RAISE_APPLICATION_ERROR(-20009,'Name cannot be updated.');
  WHEN CORRECT_NAME 
    THEN DBMS_OUTPUT.PUT_LINE('Updated.');
END;

i guess i'm messing up something with the :NEW and :OLD statement, but i can't see where. 我想我用以下内容搞砸了:NEW和:OLD语句,但我看不到哪里。

There is a typo in the table name in the 2nd line, so let's change it to EMPLOYEE. 第二行中的表名中有拼写错误,所以我们将其更改为EMPLOYEE。

AFTER UPDATE OF EMPLOYEE_NAME ON EMPLOYEE

I would try to add :NEW.EMPLOYEE_NAME before IS NOT NULL clause, but I am sure if it fixes all the problems. 我会尝试在IS NOT NULL子句之前添加:NEW.EMPLOYEE_NAME,但我确定它是否修复了所有问题。

IF(:NEW.EMPLOYEE_NAME <> :OLD.EMPLOYEE_NAME AND :NEW.EMPLOYEE_NAME IS NOT NULL)

In the trigger you do the same operation like in the update. 在触发器中,您执行与更新中相同的操作。 So - the "application" makes an update (without commit) then the trigger makes the same update and then it verifies the :new.name and the old.name . 所以 - “应用程序”进行更新(不提交),然后触发器进行相同的更新,然后验证:new.nameold.name

Try this: 尝试这个:

CREATE OR REPLACE TRIGGER NO_INVALID_NAME
BEFORE UPDATE ON EMPLOYEE 
FOR EACH ROW
DECLARE
    INVALID_NAME EXCEPTION;
    CORRECT_NAME EXCEPTION;
BEGIN
    IF :NEW.EMPLOYEE_NAME <> :OLD.EMPLOYEE_NAME AND :NEW.EMPLOYEE_NAME IS NOT NULL THEN
        RAISE INVALID_NAME;
    ELSE
        RAISE CORRECT_NAME;
    END IF;
EXCEPTION
    WHEN NOME_NON_CORRETTO
        THEN RAISE_APPLICATION_ERROR(-20009,'Name cannot be updated.');
    WHEN CORRECT_NAME 
        THEN DBMS_OUTPUT.PUT_LINE('Updated.');
END;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM