Trigger selection from same table

笑着哭i 提交于 2020-01-15 08:08:47

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!