【问题标题】:Trigger that checks if the same tuple exists in two different tables检查相同元组是否存在于两个不同表中的触发器
【发布时间】:2015-02-17 02:31:37
【问题描述】:

我写了以下代码:

CREATE OR REPLACE TRIGGER CHECK_tuple
BEFORE INSERT ON tableB
FOR EACH ROW
DECLARE IS_JOIN BOOLEAN:=FALSE

BEGIN
    SELECT tableB.column1, tableB.column2,
        CASE
         WHEN IS_JOIN:= FALSE THEN raise_application_error(-20101, 'ERROR.');
         ELSE IS_JOIN:= TRUE
        END AS CHCK_JOIN
FROM tableB 
JOIN tableA 
ON tableB.column1=tableA.column1 AND tableB.column2=tableA.column2;

END;

我必须检查表 A 中是否存在元组 (t1)(使用“元组”,我的意思是表的整行具有多列)。如果存在,它必须与表 B 中的 t2 匹配。在将元组 t2 插入表 B 之前,触发器必须激活。如果 t1 与 t2 不匹配,标志 IS_JOIN 将保持为 FALSE,Oracle SQL 将给出错误。否则,如果 t1 等于 t2,则 IS_JOIN 将为 TRUE,并且不会采取任何措施。我希望对将在表 B 中插入的每一行进行此“检查”。这是正确的方法吗?如果任务不清楚,请询问更多信息。

【问题讨论】:

  • 为什么不直接使用外键?
  • 而不是触发器?因为我正在为大学的论文编写一个示例代码,它显示了触发器的工作原理。希望我能抓住你的问题,我对 DB 理论有点陌生

标签: sql oracle join triggers


【解决方案1】:

做这样的事情的正确方法:

CREATE OR REPLACE TRIGGER test_test_CHECK_tuple
BEFORE INSERT ON tableB
FOR EACH ROW
declare
  v_cnt number(10);
BEGIN
    SELECT count(*)
    into v_cnt
    FROM tableA
    where column1=:new.column1
    and  column2=:new.column2;

  if v_cnt= 0 then
    raise_application_error(-20101, 'ERROR.');
  end if;
END;

:new 表示要插入的值。没有其他方法可以使用该值。

顺便说一句。 foreign key 并不是这样工作的,因为 foreign key 被分配给 primary keyunique key

【讨论】:

  • 你能添加一些关于“v_cnt”的cmets吗?以及你为什么使用:where column1=:new.column1 and column2=:new.column2; 非常感谢你的时间:)
  • 我做了一个编辑,希望它能回答一些问题。
  • 让我们看看我是否明白:你用“v_cnt”声明了一个计数器。然后你计算tableA中column1和column2等于tableB的column1和column2的所有行。之后你将匹配的数量存储在“v_cnt”中。最终,如果 v_cnt=0 意味着没有找到匹配项,那么我会得到一个错误。如果 v_cnt 不为零,则表示我有一些匹配项。对吗?
  • 在一个非常基本的层面上:是的。与foreign key 的区别在于,由于它连接到unique/primary key,它只能在另一个表中找到一个匹配项,并且它并没有真正查看另一个表,而是在该表的索引中。
  • 完美,这就是我想要的。也感谢外键解释
猜你喜欢
  • 2017-03-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-29
  • 2023-04-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多