【问题标题】:SQL Server 2008 :: Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >=SQL Server 2008 :: 子查询返回超过 1 个值。当子查询跟随 =、!=、<、<=、>、>= 时,这是不允许的
【发布时间】:2014-10-21 08:39:50
【问题描述】:

我在用户信息表上有 [ReconcileUserInformationComputed] 触发器

用户信息表有以下行 [ID] ,[CompanyID] ,[Status] ,[FirstName] ,[LastName]

UserinformationComputed 表有以下行 [id] ,[CompanyID] ,[law_id] ,[Status] ,[FirstName] ,[LastName]

下面是我的触发器

USE [einvoice]
GO
/****** Object:  Trigger [dbo].[ReconcileUserInformationComputed]    Script Date:    08/27/2014 10:53:08 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO



ALTER TRIGGER [dbo].[ReconcileUserInformationComputed] ON [dbo].[UserInformation] AFTER INSERT,DELETE,UPDATE
AS 
    IF @@ROWCOUNT = 0 -- exit trigger when zero records affected
    BEGIN
        RETURN
    END
    SET NOCOUNT ON;
    IF EXISTS (SELECT * FROM INSERTED)
    BEGIN
        IF EXISTS (SELECT * FROM DELETED)
        BEGIN
            --UPDATE
                UPDATE [dbo].[UserInformationComputed]
                SET -- use new values from inserted 
                CompanyID = (SELECT CompanyID from inserted),
                law_id = (SELECT ID FROM inserted),
                Status = (SELECT Status FROM inserted),
                FirstName = (SELECT FirstName FROM inserted),
                LastName = (SELECT LastName FROM inserted),
    WHERE  -- use original values from deleted
                law_id = (SELECT ID FROM deleted)
    END
    ELSE
    BEGIN
        --INSERT
      INSERT INTO [dbo].[UserInformationComputed] (CompanyID,law_id,Status,FirstName,LastName)
     SELECT CompanyID,id,Status,FirstName,LastName) FROM inserted
   END
END
ELSE IF EXISTS(SELECT * FROM DELETED)
BEGIN
    --DELETE
    DELETE FROM [dbo].[UserInformationComputed]
    WHERE law_id = (SELECT id FROM deleted)
END

当尝试在用户信息上更新多个用户时 以下错误

Msg 512, Level 16, State 1, Procedure ReconcileUserInformationComputed, Line 16
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.

我根据对上述触发器有效的答案进行了更改,但相同的更改对另一个触发器无效

ALTER TRIGGER [dbo].[ReconcileCrossRefComputed] ON [dbo].[CrossRef] AFTER INSERT, UPDATE, DELETE
AS
    IF @@ROWCOUNT = 0 -- exit trigger when zero records affected
    BEGIN
       RETURN
    END
    SET NOCOUNT ON;
    IF EXISTS (SELECT * FROM INSERTED)
    BEGIN
        IF EXISTS (SELECT * FROM DELETED)
        BEGIN
            --UPDATE
            UPDATE [dbo].[CrossRefComputed]
            SET -- use new values from inserted 
            SenderId = inserted.SenderId,
            ReceiverId = inserted.ReceiverId,
            ForeignRef = inserted.ForeignRef,
            PolicyID = inserted.PolicyID,
        From inserted
        WHERE -- use original values from deleted
        [CrossRefComputed].SenderId = inserted.SenderId
        AND [CrossRefComputed].ReceiverId = inserted.ReceiverId
    END
    ELSE
    BEGIN
        --INSERT
        INSERT INTO [dbo].[CrossRefComputed] (SenderId, ReceiverId, ForeignRef, PolicyID)
        SELECT SenderId, ReceiverId, Effective, PolicyID FROM inserted
    END
END
ELSE IF EXISTS(SELECT * FROM DELETED)
BEGIN
    --DELETE
    DELETE FROM [dbo].[CrossRefComputed]
    WHERE SenderId in (SELECT SenderId FROM deleted)
    AND ReceiverId in (SELECT ReceiverId FROM deleted)
END

谁能帮我解决更新多条记录的过程?

【问题讨论】:

  • 不要将= 用于多结果子查询。请改用IN (...)`。
  • like CompanyID in (SELECT CompanyID from inserted) ?
  • 你是如此接近... 1 个值 = 1 个值或(值列表)中的 1 个值...从不 1 个值 = 值列表
  • 是 CompanyID 在 (SELECT * from insert) 吗?我是 sql 的初学者,所以如果这个不正确,请不要误会我的意思

标签: sql-server-2008 tsql stored-procedures triggers


【解决方案1】:

请注意,UPDATE 或 DELETE 可能会影响多条记录,您的触发器必须立即处理它们,在这种情况下,您的“插入”或“删除”表将包含多条记录。

您必须在 DML 中使用联接。像这样的:

UPDATE [dbo].[UserInformationComputed]
                SET
                CompanyID = inserted.CompanyID,
                law_id = inserted.ID,
                Status = inserted.Status,
                FirstName = inserted.FirstName,
                LastName = inserted.LastName
            from inserted
    WHERE  
                UserInformationComputed.law_id = inserted.ID

我还没有完全理解你的 UPDATE 逻辑,所以你必须调整我的代码。

在您的 DELETE 命令中,您可能只需将“=”更改为“in”:

DELETE FROM [dbo].[UserInformationComputed]
    WHERE law_id in (SELECT id FROM deleted)

看看这个:

http://msdn.microsoft.com/en-us/library/ms190752.aspx

【讨论】:

  • #Caffe 我按照您对 UserInformationComputed 触发器的建议进行了更改,它有效,但它不适用于 triiger ReconcileCrossRefComputed(在我的答案中更新)
  • 子查询返回超过 1 个值。当子查询跟随 =、!=、、>= 或子查询用作表达式时,这是不允许的。
  • @RanPaul 我在你的 ReconcileCrossRefComputed 过程中看不到任何子查询,所以这是一个非常奇怪的错误。完整的错误信息告诉触发器名称和行号,对吗?真的是“ReconcileCrossRefComputed”引发错误的人吗?在哪一行?
  • Msg 512,级别 16,状态 1,过程 ReconcileCrossRefComputed,第 13 行(即 UPDATE [dbo].[CrossRefComputed])
  • @RanPaul 哦,伙计!我很失望。这对我来说没有意义;此触发器中没有子查询。你确定你真的在执行你粘贴在你的问题中的这段代码吗?
猜你喜欢
  • 2011-02-08
  • 2012-06-04
  • 2016-08-02
  • 2019-10-13
  • 1970-01-01
相关资源
最近更新 更多