比较:使用触发器插入的新值

问题描述 投票:0回答:2

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

基本上我的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
2个回答
1
投票

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

您的代码问题(除了Gordon指出的错误之外)与Postgres等其他DBMS不同,在Oracle中,您不能在像EXISTS这样的PL / SQL表达式/语句中使用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


1
投票

您不需要重复表名:

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将成为该表的主键。

© www.soinside.com 2019 - 2024. All rights reserved.