14

我想在将数据插入表之前禁用表上的特定触发器,但不会影响可能正在更改同一表中数据的其他用户。我找不到任何记录在案的方法来做到这一点。这是 Oracle 11g。

我能想到的最佳解决方案是创建一个会话变量,并让我的应用程序将其设置为触发器在工作之前检查的某个值。

强制性反触发评论:我讨厌触发。

4

4 回答 4

4

将变量添加到现有包规范(或创建新包):

enable_trigger boolean := true;

将触发器中的代码用:

如果 enable_trigger 那么

万一;

当您想“禁用”触发器时,请将变量设置为 false。

最佳实践是将变量放在正文中并编写一个 set 过程和一个 get 函数。

于 2013-03-27T13:47:59.930 回答
3

我认为在 oracle 或其他 rdbms 中不可能为特定会话禁用触发器。

我的解决方案是,如果您知道登录的 CURRENT_USER 或 session_id,那么您可以在触发器中添加条件。

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

  END IF; 

这个条件你需要把你的触发器

于 2013-03-27T12:59:10.727 回答
3

使用dbms_application_info.set_client_info(链接到 oracle 文档)在过程中设置_client_info 并在触发器中读取它。

简单的例子:

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;

在您的程序中:

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;

在你触发:

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;

完全禁用而不用担心并发

 procedure spname is
    begin    
      EXECUTE IMMEDIATE 'ALTER TRIGGER Triggername DISABLE';
      UPDATE tableName set a=b;
      EXECUTE IMMEDIATE 'ALTER TRIGGER Triggername ENABLE';
   end;
于 2018-11-20T17:05:06.080 回答
2

也许 Oracle 版本对此有用?在另一个版本中创建不同的触发器并更改会话以使用该版本。

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

我必须承认,我对版本没有实际经验。

于 2013-03-27T13:30:24.360 回答