我想问一个关于触发器的问题。假设我有一个表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。
答案 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)中进行操作。在这两种情况下,代码都是可读和可维护的。