子查询在触发器 运行 时返回了超过 1 个值

Subquery returned more than 1 value when trigger run

我正在尝试创建 DML 触发器以在 2 table 秒内完成某些删除和更新操作,

我有 3 个 table:payments_yearlypayments_yearly_detailscheque_in

payments_yearly table 有所有付款并且这些付款有详细信息(付款方式和金额)保存在 payments_yearly_details 中,付款方式可以是现金、签证、支票。检查详细信息将保存在 cheque_in table.

我有一个查询,它获取付款信息​​ + 来自详细信息的总和值,如下所示:

SELECT dbo.payments_yearly.ID, SUM(dbo.payments_yearly_details.value) AS value, dbo.payments_yearly.note,
dbo.payments_yearly.date, dbo.payments_yearly.app_user FROM dbo.payments_yearly INNER JOIN
dbo.payments_yearly_details ON dbo.payments_yearly.ID = dbo.payments_yearly_details.pay_id where payments_yearly.con_id=@con_id
GROUP BY dbo.payments_yearly.ID, dbo.payments_yearly.con_id, dbo.payments_yearly.note, dbo.payments_yearly.date, dbo.payments_yearly.app_user

所以我创建了一个触发器来删除 cheque_in table 中的所有支票,如果用户从 payments_yearly table 中删除付款,我的触发器如下所示:

ALTER TRIGGER [dbo].[delete_cheque_after_delete_payment] on [dbo].[payments_yearly]
AFTER Delete
AS 
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;

Declare @payid as int
set @payid= (select ID from payments_yearly_details where pay_id=(SELECT deleted.ID FROM deleted) and method =N'شيك')
Delete from cheque_in where pay_id =@payid

END

但是当我从payments_yearly中删除任何付款时,支票也没有删除,所以我不知道这里的错误在哪里。 我试图将 @pay_id 值从 cheque_in table 更改为静态值,例如 25,但它与我创建的另一个触发器冲突,以更新 payments_yearly_details table 当用户更改支票值或删除与付款相关的支票时,支付方式支票的价值“因为该值可能来自多张支票”,触发如下:

ALTER TRIGGER [dbo].[Update_payments_yearly_detailson_cheque_UpdateDelete] on [dbo].[cheque_in]
after UPDATE, DELETE
AS 
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;

IF EXISTS (SELECT 1 FROM payments_yearly_details WHERE ID=(SELECT deleted.pay_id FROM deleted)) 
BEGIN
Declare @value as decimal(10,2)
set @value= (SELECT SUM(cheque_in.cheque_value) from cheque_in where cheque_in.pay_id = (SELECT deleted.pay_id FROM deleted))
Update payments_yearly_details set value=@value where ID=(SELECT deleted.pay_id FROM deleted)
END
END

此触发器运行良好,并在删除支票或更新支票值时更新付款值,但它与第一​​个触发器发生冲突并显示此错误消息: System.Data.SqlClient.SqlException: 'Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression. The statement has been terminated.'

我是触发器的新手,所以我的问题是:为什么我的第一个触发器不起作用?以及如果我为第一个触发器分配了一个静态值(在检查中,在这种情况下我的触发器工作),为什么我在第二个触发器上收到错误消息。

谢谢。

您的问题是:

 (select ID from payments_yearly_details where pay_id=(SELECT deleted.ID FROM deleted) and method =N'شيك')

如果此语句 returns 超过一个值,您将得到您提到的错误。你不能用标量子查询来做到这一点。我的意思是除了系统抛出严重错误之外——想想看——我的变量现在等于这个和那个?那没有意义。

您可以像使用 DISTINCT 或 GROUP BY 那样使用廉价的 hack 来修复它,但这并不能解决事情的逻辑方面。

编辑

所以你刚刚指出了你的问题:

 (SELECT deleted.ID FROM deleted)

如果您一次删除多个 ID,您将收到此错误。

编辑 2

所以现在我们知道您每行有多个 ID,并且我们知道您尝试分配给变量的方式不起作用,所以试试这个。

改变这个:

Declare @payid as int
set @payid= (select ID from payments_yearly_details where pay_id IN (SELECT deleted.ID FROM deleted) and method =N'شيك')
Delete from cheque_in where pay_id =@payid

为此:

Delete from cheque_in where pay_id IN ((select ID from payments_yearly_details where pay_id IN ((SELECT deleted.ID FROM deleted)) and method =N'شيك'))