是否可以为当前会话禁用Oracle触发器?

时间:2013-03-27 12:47:51

标签: oracle triggers

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

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

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

4 个答案:

答案 0 :(得分:3)

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

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

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

  END IF; 

这种情况需要放入触发器

答案 1 :(得分:2)

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

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

我必须承认我没有版本的实践经验。

答案 2 :(得分:2)

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

enable_trigger boolean := true;

用以下代码包围触发器中的代码:

if enable_trigger then

end if;

如果要“禁用”触发器,请将变量设置为false。

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

答案 3 :(得分:1)

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

简单示例:

<div class="pr-2 pl-2">
  <app-name-header></app-name-header>
  <app-primary-nav></app-primary-nav>

  <div class="container-fluid row m-0 pr-0 pl-0">
    <div class="col-md-9 pl-0 pr-0">
      <app-nav-section-display></app-nav-section-display>
    </div>
    <div #twitterBarContainingDiv class="col-md-3 mt-2 pr-0 pl-0" >
      <a #twitterBar class="twitter-timeline"  data-height="800"  data-chrome="" data-partner="tweetdeck" href="https://twitter.com/paramvirsingh_k/timelines/1056538294912212993?ref_src=twsrc%5Etfw">Curated Tweets - Curated tweets by paramvirsingh_k</a>
    </div>
  </div>
</div>

在您的程序中:

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;