【问题标题】:How to call a trigger when constraint violation occurs?发生约束冲突时如何调用触发器?
【发布时间】:2018-11-18 20:32:22
【问题描述】:

我遇到了不允许用户输入重复值的情况。如果用户尝试添加重复值,系统会将用户的详细信息保存在审计表中。触发器用于此。我的代码在下面

create or replace trigger tr_add_on_audit_table
before insert on lds_consultant
for each row
declare
uname varchar2(30);
begin
 select username into uname from lds_consultant where username = :NEW.USERNAME;

 if uname <> '' or uname <> null then
  insert into audit_table values(null, null, 'nishan', 'insert', null, null, 'cmd', null, 'LDS_CONSULTANT', 'CONSULTANT_ID',null, null, null);
 end if;
end;

但此代码不会将数据插入到审计表中。

我怎样才能做到这一点?

【问题讨论】:

    标签: sql database oracle plsql triggers


    【解决方案1】:

    NULL 不等于也不不同于任何东西。您应该使用IS NULLIS NOT NULL,而不是&lt;&gt;=

    类似这样的:

    create or replace trigger tr_add_on_audit_table
      before insert on lds_consultant
      for each row
    declare
      uname varchar2(30);
    begin
     select username 
       into uname 
      from lds_consultant 
      where username = :NEW.USERNAME;
    
      if uname is not null then          --> this!
        insert into audit_table 
          values(null, null, 'nishan', 'insert', null, null, 'cmd', null, 'LDS_CONSULTANT', 'CONSULTANT_ID',null, null, null);
      end if;
    exception
      when no_data_found then
        null;
    end;
    

    我包含了异常处理部分,以防 SELECT 不返回任何内容;如果不太可能,请将其删除(或正确处理;我正在做什么NULL;)。此外,如有必要,请处理其他异常。

    另外,我建议您命名要插入的所有列。今天,您知道什么值去了哪里,但一两个月后您就会忘记第三个 NULL 值应该是什么意思。

    此外,您说不允许用户输入重复的值 - 好吧,这段代码不会让它发生。

    最简单的选择是在USERNAME 列上创建一个唯一键约束,并让Oracle 处理重复项。

    如果你想自己做,你应该例如

    raise_application_error(-20000, 'Duplicate username is not allowed);
    

    但是,这不会将您的 INSERT 保存到表中,因为所有内容都将回滚。为了解决这个问题,创建一个使用 pragma automatic_transaction 并将插入提交到审计表中的过程。

    一切都会像这样:

    create or replace procedure p_audit as
      pragma autonomous_transaction;
    begin
      insert into audit_table 
        values(null, null, 'nishan', 'insert', null, null, 'cmd', null, 'LDS_CONSULTANT', 'CONSULTANT_ID',null, null, null);
      commit;
    end;
    /
    create or replace trigger tr_add_on_audit_table
      before insert on lds_consultant
      for each row
    declare
      uname varchar2(30);
    begin
     select username 
       into uname 
      from lds_consultant 
      where username = :NEW.USERNAME;
    
      if uname is not null then
        p_audit;
        raise_application_error(-20000, 'Duplicates are not allowed')
      end if;
    exception
      when no_data_found then
        null;
    end;
    /
    

    但是,再一次,为什么要打扰?唯一性是这里的关键词。

    【讨论】:

      猜你喜欢
      • 2011-03-05
      • 2015-01-02
      • 2020-04-17
      • 1970-01-01
      • 2011-11-20
      • 2015-05-27
      • 1970-01-01
      • 2021-02-10
      • 1970-01-01
      相关资源
      最近更新 更多