从同一个表中选择触发器

时间:2012-01-03 03:20:51

标签: triggers rdbms

我想问一个关于触发器的问题。假设我有一个表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
    -> //

谢谢,

致以最诚挚的问候,

Lajos Arpad。

2 个答案:

答案 0 :(得分:3)

例如,给定的触发器将在Oracle中抛出一个Mutating表异常,但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;

答案 1 :(得分:0)

尽管从技术上讲,使用自动事务处理是避免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”存储过程,该过程首先检查业务规则,计算金额,最后发出update employee ...命令。 或者,如果您制作了瘦客户端或使用持久性API,则应在应用程序服务器(例如EJB)中进行操作。在这两种情况下,代码都是可读和可维护的。