Can an Oracle trigger be disabled for the current session?

北城以北 提交于 2020-01-02 00:55:12

问题


I'd like to disable a specific trigger on a table prior to inserting data into it, but without affecting other users that may be changing data in that same table. I can't find any documented way to do this. This is Oracle 11g.

The best solution I've been able to come up with is to create a session variable and have my application set that to some value that the trigger checks for prior to doing its work.

Obligatory anti-trigger comment: I hate triggers.


回答1:


Add a variable to an existing package spec (or create a new package):

enable_trigger boolean := true;

Surround the code in the trigger with:

if enable_trigger then

end if;

When you want to "disable" the trigger set the variable to false.

A Best Practice would be to put the variable in the body and write a set procedure and a get function.




回答2:


I dont think that disabling trigger is possible for a particular session is possible in oracle or other rdbms .

My solution is that ,if you know the CURRENT_USER or the session_id from which you login ,than you can put a condition in the trigger .

  IF SYS_CONTEXT ('USERENV', 'CURRENT_USER') <> '<XYZ>' THEN
    --do the operation

  END IF; 

This condition you need to put in your trigger




回答3:


Maybe Oracle Editions are useful for this purpose? Create a different trigger in another edition and change the session to use that edition.

http://www.oracle-base.com/articles/11g/edition-based-redefinition-11gr2.php#editions

I must confess that I have no practical experience with editions.




回答4:


Use dbms_application_info.set_client_info (link to oracle documentation) to set_client_info in the procedure and read it in the trigger.

Simple example:

SET SERVEROUTPUT ON   
declare
CI_Status VARCHAR2(25 BYTE):='';
begin
--set the value
dbms_application_info.set_client_info('qwerty');
-- the value is sent an out to CI_Status when you want to read it
DBMS_APPLICATION_INFO.READ_CLIENT_INFO (CI_Status);
--Output the value in the console 
dbms_output.put_line('Value of CI_Status is: ' || CI_Status); 
end;

In your procedure:

procedure spname is
    begin
      dbms_application_info.set_client_info('qwerty');
      --Do your update
      UPDATE tableName set a=b;
      --in case you still have the sesion opened, set it to null after
      dbms_application_info.set_client_info(null);
end;

In you trigger:

create or replace TRIGGER Triggername
 BEFORE INSERT OR UPDATE
 ON tablename
 FOR EACH ROW
declare
CI_Status VARCHAR2(25 BYTE):='';
begin
--Retrieve the value into CI_Status the variable
DBMS_APPLICATION_INFO.READ_CLIENT_INFO(CI_Status); 
    IF INSERTING THEN
       null;
    ELSIF UPDATING THEN
          IF CI_Status = 'qwerty' then
             --Do nothing since you dont want the trigger to fire
              null;
          ELSIF CI_Status is null then
            :new.tablefield:= SYSDATE;
          END IF;
    END IF;
end Triggername;

To disable completely without worrying about concurrences

 procedure spname is
    begin    
      EXECUTE IMMEDIATE 'ALTER TRIGGER Triggername DISABLE';
      UPDATE tableName set a=b;
      EXECUTE IMMEDIATE 'ALTER TRIGGER Triggername ENABLE';
   end;


来源:https://stackoverflow.com/questions/15659188/can-an-oracle-trigger-be-disabled-for-the-current-session

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