I have a trigger autonomous but only execute one time in the same session

余生颓废 提交于 2020-01-07 04:00:56

问题


I have a trigger autonomous but only execute one time in the same session, then do nothing

CREATE OR REPLACE TRIGGER tdw_insert_unsus
BEFORE INSERT ON unsuscription_fact FOR EACH ROW
DECLARE
 PRAGMA AUTONOMOUS_TRANSACTION;
 v_id_suscription               SUSCRIPTION_FACT.ID_SUSCRIPTION%TYPE;
 v_id_date_suscription          SUSCRIPTION_FACT.ID_DATE_SUSCRIPTION%TYPE;
 v_id_date_unsuscription        SUSCRIPTION_FACT.ID_DATE_UNSUSCRIPTION%TYPE;
 v_suscription                  DATE;
 v_unsuscription                DATE; 
 v_live_time                    SUSCRIPTION_FACT.LIVE_TIME%TYPE;
BEGIN
    SELECT id_suscription, id_date_suscription 
    INTO v_id_suscription, v_id_date_suscription
    FROM(
        SELECT id_suscription, id_date_suscription
        FROM suscription_fact
        WHERE id_mno = :NEW.ID_MNO
        AND id_provider = :NEW.ID_PROVIDER
        AND ftp_service_id = :NEW.FTP_SERVICE_ID
        AND msisdn = :NEW.MSISDN
        AND id_date_unsuscription IS NULL
        ORDER BY id_date_suscription DESC
    )
    WHERE ROWNUM = 1;

    -- calculate time
    v_unsuscription := to_date(:NEW.id_date_unsuscription,'yyyymmdd');
    v_suscription := to_date(v_id_date_suscription,'yyyymmdd');
    v_live_time := (v_unsuscription - v_suscription);

    UPDATE suscription_fact SET id_date_unsuscription = :NEW.id_date_unsuscription, 
    id_time_unsuscription = :NEW.id_time_unsuscription, live_time = v_live_time
    WHERE id_suscription = v_id_suscription;

    COMMIT;

    EXCEPTION
        WHEN NO_DATA_FOUND THEN
        ROLLBACK;
END;
/

if I insert values works well the first o second time but after not work, but if I logout the session and login works for the first or second insertion what is the problem?, I use oracle 10g


回答1:


You're using an autonomous transaction to work around the fact that a trigger can not query its table itself. You've run into the infamous mutating table error and you have found that declaring the trigger as an autonomous transaction makes the error go away.

No luck for you though, this does not solve the problem at all:

  • First, any transaction logic is lost. You can't rollback the changes on the suscription_fact table, they are committed, while your main transaction is not and could be rolled back. So you've also lost your data integrity.
  • The trigger can not see the new row because the new row hasn't been committed yet! Since the trigger runs in an independent transaction, it can not see the uncommitted changes made by the main transaction: you will run into completely wrong results.

This is why you should never do any business logic in autonomous transactions. (there are legitimate applications but they are almost entirely limited to logging/debugging).

In your case you should either:

  1. Update your logic so that it does not need to query your table (updating suscription_fact only if the new row is more recent than the old value stored in id_date_unsuscription).
  2. Forget about using business logic in triggers and use a procedure that updates all tables correctly or use a view because here we have a clear case of redundant data.
  3. Use a workaround that actually works (by Tom Kyte).

I would strongly advise using (2) here. Don't use triggers to code business logic. They are hard to write without bugs and harder still to maintain. Using a procedure guarantees that all the relevant code is grouped in one place (a package or a procedure), easy to read and follow and without unforeseen consequences.



来源:https://stackoverflow.com/questions/20248569/i-have-a-trigger-autonomous-but-only-execute-one-time-in-the-same-session

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