【问题标题】:Trigger selection from same table从同一个表中触发选择
【发布时间】:2012-01-03 03:20:51
【问题描述】:

我想问一个关于触发器的问题。假设我有一个表 T 并且在更新之前我需要一个触发器。但是,我有一个问题。我需要使用触发器中的其他 T 行来检查条件。我的问题是:哪个 RDBMS 支持这个?我在哪里可以编写在触发器触发的同一个表上执行选择的触发器。例如:

CREATE TRIGGER updtrigger BEFORE UPDATE ON Employee
    -> FOR EACH ROW
    -> BEGIN
    -> IF NEW.Salary<=500 THEN
    -> SET NEW.Salary=10000;
    -> ELSEIF NEW.Salary>500 and NEW.Salary < 600 THEN
    -> SET NEW.Salary=15000;
    -> ELSEIF NEW.Salary > (select MAX(Salary) from Employee)
    -> Set NEW.Salary = 601;
    -> END IF;
    -> END
    -> //

谢谢,

最好的问候,

拉霍斯阿尔帕德。

【问题讨论】:

  • 这似乎很危险,充其量。我不确定是否有任何 rdbms 允许这样做。允许在 FOR EACH ROW 更新过程中对同一个表进行查询将允许在触发器中打开数据不一致的可能性。无法保证更新行的顺序。
  • 我理解这个问题,但可能需要这样做,例如,如果您想自动消除某些类型的不一致,则需要这些触发器。您的触发器如何在没有选择的情况下确定您的行是否与其他行不一致?如果您知道自己在做什么,这并不危险,但是对于那些不知道自己在做什么的人来说,这很危险。

标签: triggers rdbms


【解决方案1】:

例如,给定的触发器将在 Oracle 中引发 Mutating table 异常,但在 Oracle 中有解决方案,例如允许此触发器并且工作正常:

CREATE or replace TRIGGER updtrigger BEFORE UPDATE ON Employees
     FOR EACH ROW
DECLARE
 pragma autonomous_transaction;
 n number;
     BEGIN
     select MAX(Salary) into n from Employees;
     IF :NEW.Salary<=500 THEN
          DBMS_OUTPUT.PUT_LINE('kisebb mint 500');
          :NEW.salary:=n;
    end if;
commit;
     END;

【讨论】:

    【解决方案2】:

    虽然使用自治事务在技术上是避免 ORA-04091 的一种方法,但我不建议使用它,原因有两个:

    1.自治事务看不到调用者事务未提交的更改。例如,在以下情况下,类似上述解决方案的触发器不会给出正确的结果:

    delete from employees;    
    insert into employees (id, name, salary) values (1, 'A', 5000);
    insert into employees (id, name, salary) values (2, 'B', 1000);
    commit;
    update employees set salary=800 where id=1;
    update employees set salary=100 where id=2;
    select * from employees;
    

    在第二次更新期间,触发器中的 select 语句看不到第一次更新的结果,它会看到原始值 5000 而不是 800。但当然在某些情况下它可以工作。

    2.避免这种情况的另一个原因只是个人建议。如果您制作胖客户端,我建议创建一个“update_salary”存储过程,它首先检查业务规则,计算金额,最后发出更新员工...命令。 或者,如果您制作瘦客户端或使用持久性 API,那么您应该在应用程序服务器(例如 EJB)中进行。在这两种情况下,代码都是可读和可维护的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-15
      • 2014-01-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多