【问题标题】:SQL Subquery returned more than 1 value - on execution errorSQL 子查询返回超过 1 个值 - 执行错误
【发布时间】:2015-02-02 08:07:37
【问题描述】:

我正在尝试使用存储过程从CSD_4_00 中的另一个trade 表更新surveillance 数据库中的trade 表,如下所示:

USE [CSD_4_00]

GO
CREATE PROCEDURE [dbo].[TradeData]
AS
BEGIN
    UPDATE [surveillance].[dbo].Trade 
    SET SellerMarketMember = (SELECT [SellerMember].[MemberCode]
                                FROM Trade
                                INNER JOIN [Member] As SellerMember ON Trade.[SellerMarketMemberId] = [SellerMember].[MemberId])
    , SellerAccount = (SELECT [SellerAccount].[AccountNumber]
                        FROM Trade
                        INNER JOIN [Account] As SellerAccount ON Trade.[SellerAccountId] = [SellerAccount].[AccountId])
    , BuyerMarketMember = (SELECT [BuyerMember].[MemberCode]
                            FROM Trade
                            INNER JOIN [Member] As BuyerMember ON Trade.[BuyerMarketMemberId] = [BuyerMember].[MemberId])
    , BuyerAccount = (SELECT [BuyerAccount].[AccountNumber]
                        FROM Trade
                        INNER JOIN [Account] As BuyerAccount ON Trade.[BuyerAccountId] = [BuyerAccount].[AccountId])
    , CancelTime = (SELECT CancelTime
                        FROM Trade)

    WHERE [surveillance].[dbo].Trade.[Ticket] = (SELECT TicketNumber FROM Trade )

END
GO

但在执行时却出现以下错误:

子查询返回超过 1 个值。当子查询跟随 =、!=、、>= 或子查询用作表达式时,这是不允许的。

所以,我尝试使用我的程序的这个修改版本来解决这个问题:

CREATE PROCEDURE [dbo].[TradeData]
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    -- Insert statements for procedure here
    UPDATE [surveillance].[dbo].Trade 
    SET SellerMarketMember = [SellerMember].[MemberCode]
                                FROM Trade as T
                                INNER JOIN [Member] As SellerMember ON T.[SellerMarketMemberId] = [SellerMember].[MemberId]
    WHERE [surveillance].[dbo].Trade.[Ticket] in(SELECT TicketNumber FROM Trade )

    UPDATE [surveillance].[dbo].Trade set SellerAccount =  [SellerAccount].[AccountNumber]
                        FROM Trade as T
                        INNER JOIN [Account] As SellerAccount ON T.[SellerAccountId] = [SellerAccount].[AccountId]
    WHERE [surveillance].[dbo].Trade.[Ticket] in(SELECT TicketNumber FROM Trade )

    UPDATE [surveillance].[dbo].Trade set BuyerMarketMember = [BuyerMember].[MemberCode]
                            FROM Trade as T
                            INNER JOIN [Member] As BuyerMember ON T.[BuyerMarketMemberId] = [BuyerMember].[MemberId]
    WHERE [surveillance].[dbo].Trade.[Ticket] in(SELECT TicketNumber FROM Trade )


    UPDATE [surveillance].[dbo].Trade set BuyerAccount = [BuyerAccount].[AccountNumber]
                        FROM Trade as T
                        INNER JOIN [Account] As BuyerAccount ON T.[BuyerAccountId] = [BuyerAccount].[AccountId]
    WHERE [surveillance].[dbo].Trade.[Ticket] in(SELECT TicketNumber FROM Trade )


UPDATE [surveillance].[dbo].Trade set    CancelTime =  T.CancelTime FROM Trade as T
                        WHERE [surveillance].[dbo].Trade.[Ticket] in(SELECT TicketNumber FROM Trade )                       

END
GO

执行时没有出现错误,但我的表中得到了错误的结果。 有什么帮助吗?

【问题讨论】:

  • 您遇到的问题是,在至少一个 UPDATE 中,您的子选择或 JOIN 返回不止一行,因此 TicketNumber 在 Trade 表中不是唯一的 - 您需要使谓词准确返回1 或 0 行。

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


【解决方案1】:

希望这会给你正确的结果。

这将使您的脚本有效:

CREATE PROCEDURE [dbo].[TradeData]
AS
BEGIN
    UPDATE Trade
    SET SellerMarketMember = 
        (SELECT TOP 1 [SellerMember].[MemberCode]
         FROM [Member] As SellerMember 
         WHERE Trade.[SellerMarketMemberId] = [SellerMember].[MemberId])
    , SellerAccount = 
        (SELECT TOP 1 [SellerAccount].[AccountNumber]
         FROM [Account] As SellerAccount 
         WHERE Trade.[SellerAccountId] = [SellerAccount].[AccountId])
    , BuyerMarketMember = 
        (SELECT TOP 1 [BuyerMember].[MemberCode]
         FROM [Member] As BuyerMember 
         WHERE Trade.[BuyerMarketMemberId] = [BuyerMember].[MemberId])
    , BuyerAccount = 
        (SELECT TOP 1 [BuyerAccount].[AccountNumber]
         FROM [Account] As BuyerAccount 
         WHERE Trade.[BuyerAccountId] = [BuyerAccount].[AccountId])
         -- CancelTime looks strange. I can't tell what you are trying
    , CancelTime = 
      (SELECT CancelTime
       FROM Trade)
    FROM [surveillance].[dbo].Trade Trade
    WHERE [surveillance].[dbo].Trade.[Ticket] in (SELECT TicketNumber FROM Trade )

END

【讨论】:

  • 这将使第一个脚本在语法上安全,但它不能解决为 UPDATE 选择多个值的问题 - 它只需要其中 1 个,不一定是正确的,如OP 第二次尝试。
  • 但它所做的是加入子选择中的表,因为它应该被加入
  • 同意,这是朝着正确方向迈出的一步,但说“希望这会给你带来正确的结果”是一种误导。
  • 这是给定信息的最大努力。它应该解决错误的数据,并且应该给出与尝试查询相同的结果
【解决方案2】:

要给出正确的答案,如果您能大致了解这些表(Trade、Member 等)是什么,将会有所帮助。在我看来,Member 等应该是主表并交易事务表 - 您正在尝试使用主表中的详细信息更新事务表。如果是这样的话,我想到了一点:

SELECT [SellerMember].[MemberCode]
                            FROM Trade
                            INNER JOIN [Member] As SellerMember ON Trade.[SellerMarketMemberId] = [SellerMember].[MemberId]

当然,Trade 表将有多个记录与同一个卖家成员,因此,这就是子查询返回多个记录的原因?

如果[SellerMember].[MemberCode] 等确实是唯一值,正如我所期望的那样,上面建议的select TOP 1(或select distinct)应该给出正确的行为。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多