如何使用内部联接创建触发器

Posted

技术标签:

【中文标题】如何使用内部联接创建触发器【英文标题】:How do I create a trigger with Inner Joins 【发布时间】:2019-06-04 19:28:57 【问题描述】:

当贷款表中有插入时,我正在尝试创建一个触发器来填充 aud 贷款表。我希望这个 aud 表有来自 Loan 表和另一个表的数据,所以我试图设置获取这些数据的变量。

创建触发器时出现错误“未知系统变量 'var1'”

这是数据库布局:

https://cdn.discordapp.com/attachments/582912082450710528/583696750322253824/unknown.png

DELIMITER $$
CREATE TRIGGER Loan_Insert AFTER INSERT ON loan
FOR EACH ROW
BEGIN

SET var1 =
(SELECT loan_type.type_of_loan
FROM loan INNER JOIN loan_type ON
loan.loan_type_idloan_type = loan_type.idloan_type
AND
loan.loan_type_idapp_type = loan_type.idapp_type
WHERE loan.loan_type_idloan_type = new.loan_type_idloan_type
AND loan.loan_type_idapp_type = new.loan_type_idapp_type);

SET var2 =
(SELECT loan_type.app_type
FROM loan INNER JOIN loan_type ON
loan.loan_type_idloan_type = loan_type.idloan_type
AND
loan.loan_type_idapp_type = loan_type.idapp_type
WHERE loan.loan_type_idloan_type = new.loan_type_idloan_type
AND loan.loan_type_idapp_type = new.loan_type_idapp_type);


INSERT INTO Aud_Loan(bk_Loan, type_of_loan, type_of_loan_description, application_type,
application_type_description, insert_date)
VALUES(new.idloan, new.loan_type_idloan_type, var1, new.loan_type_idapp_type, var2,CURDATE());
END $$

【问题讨论】:

你需要声明变量。 感谢您的回答。我忘记了。我通过在变量名称前添加 @ 来声明变量。这让我可以创建触发器。现在,当我尝试在触发器设置的表中插入一行时出现错误,即“子查询返回超过 1 行”,我相信它与我的触发器有关。你知道问题可能是什么吗? 用于检索 var1 和/或 var2 值的查询可能会返回多个结果;您需要确定获得单个结果的适当方法。 (LIMIT 1 会起作用,但如果您要返回多行,您可能应该仔细检查您的逻辑以确保您使用的是正确的。) 谢谢,就是这样!我现在的问题是它获得了两次值,因为有 2 笔贷款具有相同的 loan_type 和 app_type。但我希望只得到一次。我尝试了所有类型的连接(INNER、LEFT、RIGHT...),但都不起作用 看起来您实际上并不需要这些查询来引用loan 并加入loan_type;您应该可以使用您的 new. 值直接从 loan_type 中进行选择。 【参考方案1】: 局部变量必须是DECLAREd。 docs 使用 SET 时,右侧只能返回一个值(单个结果和单个字段)。

在您的特定情况下,您可能可以像这样调整 SET 语句中使用的查询:

SET var1 = (
   SELECT loan_type.type_of_loan
   FROM loan_type 
   WHERE loan_type.idloan_type = NEW.loan_type_idloan_type
      AND loan_type.idapp_type = NEW.loan_type_idapp_type
);

您甚至可以使用SELECT INTO 将其减少为一个查询:

SELECT loan_type.type_of_loan, loan_type.app_type
INTO var1, var2
FROM loan_type 
WHERE loan_type.idloan_type = NEW.loan_type_idloan_type
   AND loan_type.idapp_type = NEW.loan_type_idapp_type
;

【讨论】:

感谢您的回答,这确实有帮助,但我仍然通过该选择获得了几个值(因为有 2 笔贷款具有相同的贷款类型和应用类型)。我想我可以通过使用“SELECT DISTINCT”来解决这个问题。有没有更好的办法? 只有在多个贷款_type具有这些值的情况下,该选择才应给出多个结果; (编辑:第二个有一个转录错误,将 AND 放在查询之外......如果您忽略该条件,如果多个loan_types 具有相同的 idloan_type 值,这可能会导致问题。) 谢谢,这确实很好用!我只是好奇,我怎样才能使它与 INNER JOIN 一起工作? (对于我想去更多桌子的情况)。我试过这样做:sql SELECT loan_type.type_of_loan FROM loan_type INNER JOIN loan ON loan.loan_type_idloan_type = loan_type.idloan_type AND loan.loan_type_idapp_type = loan_type.idapp_type WHERE loan.loan_type_idloan_type = 9 AND loan.loan_type_idapp_type = 1 但它返回多个值 您会得到多个结果,因为您无法使用这些值唯一标识特定的 loan 记录;如果loan 有一个主键值,最好使用它而不是其他贷款可能共享的值。 谢谢,这是有道理的。向选择添加“DISTINCT”也可以(因为所有值都相同)。非常感谢您的意见

以上是关于如何使用内部联接创建触发器的主要内容,如果未能解决你的问题,请参考以下文章

如何在 EF Core 中将内部联接与计算列一起使用?

CakePHP:如何使用内部联接从两个表中检索数据?

如何使用 Spark sql 在 Databricks 中使用内部联接更新 Databricks Delta 表

如何将此 SQL 内部联接查询转换为 LINQ 语法?

如何将 SQL 中的多个内部联接转换为 LINQ?

如何在两个表之间创建正确的联接?