SQL Server 子查询返回了多个值,当子查询跟在=、!=、〈、〈=、>、>=之后或子查询用作表达式[已关闭]时,不允许出现这种情况

js4nwp54  于 2023-01-16  发布在  其他
关注(0)|答案(2)|浏览(125)

已关闭。此问题需要details or clarity。当前不接受答案。
**想要改进此问题?**添加详细信息并通过editing this post阐明问题。

2天前关闭。
Improve this question
所以,我尝试在我的C#程序上使用这个SQL Server触发器:
但我得到了一个错误,并说:
System.Data.SqlClient.SqlException:'子查询返回了多个值。当子查询跟在=、!=、〈、〈=、〉、〉=之后或子查询用作表达式时,不允许出现这种情况。语句已终止。'
我应该如何处理此错误?

ALTER TRIGGER [dbo].[ComputeTotal] 
ON [dbo].[tblPurchase]
AFTER INSERT, DELETE, UPDATE
AS 
BEGIN
    SET NOCOUNT ON;

    UPDATE tblPurchase 
    SET VatDiscount = (DiscountedQuantity * (.12*Price)) 
    
    UPDATE tblPurchase 
    SET VatTotal = (DiscountedQuantity * Price) - VatDiscount

    UPDATE tblPurchase 
    SET Discount = DiscountedQuantity * (.20*Price)

    UPDATE tblPurchase 
    SET NormalDiscountTotal = (Price * DiscountedQuantity) - Discount
    
    IF (SELECT VatDiscount FROM tblPurchase) = 0.00
        UPDATE tblPurchase 
        SET Total = (Quantity * Price)

    IF (SELECT VatTotal FROM tblPurchase) > 0.00
        UPDATE tblPurchase 
        SET Total = (VatTotal - (VatTotal * .20))
END
xriantvc

xriantvc1#

您所得到的特定异常可能是由以下代码行引起的:

IF (SELECT VatDiscount FROM tblPurchase) = 0.00

如果tblPurchase中有多行,上面的SELECT将返回多个值。您希望如何将这些多个值与0.00进行比较?您没有将此告知SQL Server,因此它会引发错误。相反,您可以执行以下操作...

IF 0.00 = ALL(SELECT VatDiscount FROM tblPurchase)

或者...

IF 0.00 = ANY(SELECT VatDiscount FROM tblPurchase)

...以避免异常,但我认为这也不是您真正想要的,因为IF下面的UPDATE仍然会修改所有行,而不仅仅是那些满足IF的行。
而且,奇怪的是,您没有使用inserteddeleted伪表,触发器通常对插入/更新/删除的行进行操作,这些行可以通过这些伪表访问。
请注意,即使INSERT语句插入多行,触发器也只会被调用一次(UPDATE和DELETE也是如此)。也就是说,触发器可以在一次调用中处理多行,因此inserteddeleted伪表可以包含多行。
在您的例子中,您可能希望将折扣应用于插入的新购买,而不是旧购买,对吗?您可以通过在UPDATE语句中加入inserted来实现这一点,如下所示:

UPDATE tblPurchase
SET
    VatDiscount = (DiscountedQuantity * (.12*Price))
FROM
    inserted
    JOIN tblPurchase
        ON inserted.PurchaseId = tblPurchase.PurchaseId

等等
另外,考虑一下你是否真的需要AFTER INSERT, DELETE, UPDATE触发器。也许只需要AFTER INSERT就足够了?
此外,考虑将所有这些单独的UPDATE语句合并为一个。不要害怕根据需要将公共逻辑放入公共表表达式(也称为CTE -在WITH子句下)。例如,您可以先在CTE中计算VatDiscount,然后将其分配给表中的字段 * 和 *,并将其用作另一个计算的一部分。

uz75evzq

uz75evzq2#

在您的情况下,您使用此查询SELECT VatTotal FROM tblPurchase返回多个值,并与单个值进行比较您的查询可以简化为

UPDATE tblPurchase 
    SET Total = (Quantity * Price)
    Where VatDiscount =0.00
    UPDATE tblPurchase 
    SET Total = (VatTotal - (VatTotal * .20))
    Where VatDiscount = xxx

相关问题