Chinook数据库的SQL触发器:总和为null时的条件
我正在复习我的SQL,并使用Chinook数据库进行练习 数据模型可在此处找到: 目标是编写触发器,以便在插入或删除发票行时更新发票表中的合计Chinook数据库的SQL触发器:总和为null时的条件,sql,sql-server,triggers,conditional,Sql,Sql Server,Triggers,Conditional,我正在复习我的SQL,并使用Chinook数据库进行练习 数据模型可在此处找到: 目标是编写触发器,以便在插入或删除发票行时更新发票表中的合计 CREATE TRIGGER UpdateTotal ON InvoiceLine AFTER INSERT, DELETE AS UPDATE Invoice SET Total = ( SELECT sum(LineSum) AS InvoiceTotal FROM ( SELE
CREATE TRIGGER UpdateTotal ON InvoiceLine
AFTER INSERT, DELETE
AS
UPDATE Invoice
SET Total = (
SELECT sum(LineSum) AS InvoiceTotal
FROM (
SELECT InvoiceId, (UnitPrice * Quantity) AS LineSum
FROM InvoiceLine
) AS WithLineSum
GROUP BY InvoiceId
HAVING WithLineSum.InvoiceId = Invoice.InvoiceId
)
当我插入和删除发票行记录时,除了删除发票的最后一个发票行外,这非常有效。当我这样做时,我会得到错误:
无法在“Chinook.dbo.Invoice”表的“Total”列中插入空值;列不允许空值。
更新失败
所以基本上,如果sum(LineSum)为空,我需要将其设置为零
我正在努力弄清楚如何构造条件查询,有人能帮忙吗?基本上,您应该将子查询封装在一个联合体中
SET Total = COALESCE(...subquery..., 0)
每当一条记录发生更改时,此触发器将更新您不希望执行的每个发票。您需要查看插入和删除的伪表,以便仅更新已更改的发票
接下来,考虑不要使用相关的子查询。您需要尽可能快地使用触发器代码,并且使用联接进行更新很可能更快(当然是测试)
最后,您可以对求和使用coalesce,这样,如果它为null,它将把sume更新为零 您的方法效率低下,因为您每次都在更新每个发票,而不是只更新受操作影响的发票。您需要利用触发器中的特殊功能
CREATE TRIGGER UpdateTotal ON InvoiceLine
AFTER INSERT, DELETE
AS
SET NOCOUNT ON;
UPDATE Inv
SET Total = Total + (i.UnitPrice * i.Quantity)
FROM Inserted i
INNER JOIN Invoice Inv
ON i.InvoiceId = Inv.InvoiceId;
UPDATE Inv
SET Total = Total - (d.UnitPrice * d.Quantity)
FROM Deleted d
INNER JOIN Invoice Inv
ON d.InvoiceId = Inv.InvoiceId;
@user3689167:我刚刚在我的本地机器上测试了这个,它工作正常。