问题
I would like to ask a question about triggers. Let's say that I have a table T and I need a trigger before update. However, I have a problem. I need to check a condition using the other rows of T from the trigger. My question is: Which RDBMS's support this? Where can I write triggers which perform selection(s) on the same table where the trigger fires. For instance:
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
-> //
Thank you,
Best regards,
Lajos Arpad.
回答1:
The given trigger will throw an Mutating table exception in Oracle, for example, but there is a solution in Oracle, for instance this trigger is allowed and it works fine:
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:
Although using autonomous transaction is technically is a way for avoid ORA-04091, I do not recommend using it for two reasons:
1.Autonomous transaction can't see uncommitted changes of the caller transaction. For example the trigger like above solution does not give the right result in the following case:
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;
During the second update the select statement in the trigger can't see the result of the first update, it will see the original value of 5000 not the 800. But of course it can work in some cases.
2.The other reason to avoid this is only a personal suggestion. If you make thick client I recommend to create an "update_salary" stored procedure which check business rules first, calculates the amounts, finally issues the update employees... command. Or if you make a thin client or or using a persistence api then you should do it in application server (e.g. EJB). In both cases the code will readable and maintainable.
来源:https://stackoverflow.com/questions/8707556/trigger-selection-from-same-table