【问题标题】:Comparing :new value inserted with a trigger比较:用触发器插入的新值
【发布时间】:2019-08-10 13:56:45
【问题描述】:

我正在尝试构建一个触发器来检查要插入的行是否存在于另一个表中。

基本上我的 2 个表共享一列 ID。 当新行在另一个表中至少不存在一次时,我想阻止插入。

我有这个:

create or replace trigger BIM
before insert on TABLE1 
for each row
begin
    if not exists (select 1 from TABLE2 where TABLE2.ID = :new.TABLE1.ID)
then
    raise_application_error(-20634, 'Error');
  end if;
end;

但我明白了:

PLS-00049: bad bind variable 'NEW.TABLE1'

【问题讨论】:

    标签: sql oracle oracle11g triggers database-trigger


    【解决方案1】:

    Gordon 是对的,在这种情况下最好使用外键约束。

    您的代码的问题(除了 Gordon 指出的错误之外)是,与 Postgres 等少数其他 DBMS 不同,在 Oracle 中,您不能在 PL/SQL 表达式/语句中使用 EXISTS,例如 IF。应该是纯 SQL 语句。

    create or replace trigger BIM
    before insert on TABLE1 
     for each row
    declare 
    l_id_exists INT;
    begin
        select CASE WHEN 
                     exists (select 1 from TABLE2 where TABLE2.ID = :new.ID) 
                 THEN 1 
            ELSE 0 END INTO l_id_exists from dual;
       if l_id_exists = 0
       then
        raise_application_error(-20634, 'Error');
      end if;
    end;
    /
    

    DEMO

    【讨论】:

      【解决方案2】:

      表名无需重复:

      create or replace trigger BIM
      before insert on TABLE1 
      for each row
      begin
          if (select 1 from TABLE2 where TABLE2.ID = :new.ID and rownum = 0) is not null
      then
          raise_application_error(-20634, 'Error');
        end if;
      end;
      

      也就是说,这是一个奇怪的要求。我建议您使用外键约束,但您明确地说“至少一次”。这使我怀疑您的数据模型不正确——您缺少某种实体,其中id 将是该表的主键。

      【讨论】:

      • 好吧,这不是一个坏模型,我应该创建一个断言来检查表 1 上的每条新记录是否存在于表 2 中。顺便说一句,我尝试了你的代码并且它是正确的,但现在我'收到以下错误:Errors: TRIGGER BIM Line/Col: 2/5 PL/SQL: Statement ignored Line/Col: 2/12 PLS-00204: function or pseudo-column 'EXISTS' may be used inside a SQL statement only
      • @KekaBron 。 . .您应该使用外键约束。
      猜你喜欢
      • 1970-01-01
      • 2021-06-19
      • 1970-01-01
      • 1970-01-01
      • 2020-03-09
      • 1970-01-01
      • 2020-10-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多