【问题标题】:Subquery returned more than one value error子查询返回多个值错误
【发布时间】:2015-01-19 06:38:27
【问题描述】:

我正在使用以下查询,但它引发了错误。它在某些情况下可以正常工作,具体取决于 id,但并非适用于所有情况。

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

Set @NoOfRows = (Select COUNT(*)  from @TempT)

While @i <= @NoOfRows
Begin
  SET @Voucher_No=( select V_No from @TempT where RowID=@i)
  SET @Voucher_Type_No=( select voucher_type_no from @TempT where RowID=@i)
  SET @Voucher_Id=( select Voucher_Id from @TempT where RowID=@i)
  set @strPartyName=''
  set @strPartyName = (Select Party_Name from Cheque_Book where Voucher_No=   @Voucher_No   and Voucher_Type_No=   @Voucher_Type_No   and Company_No=  @Comp_No   and Bank_Account_No= @dbc_Account )

  if NULLIF(@strPartyName,'') IS NULL
  begin
    set @strPartyName =(Select a.account_name from Voucher v inner join account a on v.Account_No = a.account_No where v.Voucher_Id= @Voucher_Id)
    Update @TempT Set Party_Name =@strPartyName Where RowID =@i
    set @i=@i+1
  end
End
Select * from @TempT

【问题讨论】:

  • 你遇到了什么错误?
  • 正如错误所说,您的任何选择查询都返回多个值,这就是您出错的原因?在每次选择查询后使用 Print 进行调试,以便您可以找到错误的确切位置或创建 sqlfiddle。
  • 您的一个 SELECT 语句返回多个值而不是返回单个值。尝试为该特定 ID 单独运行每个 select 语句。
  • 您的一些子查询返回的值超过了值.. 单独执行子查询并验证
  • @temp 表返回超过 200 行,几乎不可能调试每一行的值

标签: sql sql-server tsql


【解决方案1】:

不是使用子查询设置变量,而是如下所示设置变量。

SELECT @NoOfRows = COUNT(*) FROM @TempT

WHILE @i <= @NoOfRows
BEGIN
    SELECT @Voucher_No = V_No FROM @TempT WHERE RowID=@i
    SELECT @Voucher_Type_No = voucher_type_no FROM @TempT WHERE RowID=@i
    SELECT @Voucher_Id = Voucher_Id FROM @TempT where RowID=@i
    SET @strPartyName=''

    SELECT @strPartyName =  Party_Name FROM Cheque_Book WHERE Voucher_No = @Voucher_No AND Voucher_Type_No = @Voucher_Type_No   AND Company_No=  @Comp_No   AND Bank_Account_No= @dbc_Account
    IF NULLIF(@strPartyName,'') IS NULL
    BEGIN
        SELECT @strPartyName = a.account_name FROM Voucher v INNER JOIN account a ON v.Account_No = a.account_No WHERE v.Voucher_Id= @Voucher_Id
        UPDATE @TempT SET Party_Name = @strPartyName WHERE RowID = @i
        SET @i = @i + 1
    END
END 
SELECT * FROM @TempT

【讨论】:

    【解决方案2】:

    它表明您的子查询返回多个值。

    您必须使用 TOP 关键字修改您的子查询,或提供更多过滤器(where 条件和 order by),只返回一个值。

    While @i <= @NoOfRows
     Begin
    
       SET @Voucher_No=( select top 1 V_No from @TempT where RowID=@i)
       SET @Voucher_Type_No=( select top 1 voucher_type_no from @TempT where RowID=@i)
       SET @Voucher_Id=( select top1 Voucher_Id from @TempT where RowID=@i)
    ......
    END
    

    要解决此问题,您只需在 while 循环中运行实际的 select 查询,它会给出超过 2 个值的结果,例如

    While @i <= @NoOfRows
    Begin
    
       --SET @Voucher_No=( 
       select  V_No from @TempT where RowID=@i --)
       --SET @Voucher_Type_No=( 
       select  voucher_type_no from @TempT where RowID=@i --)
       --SET @Voucher_Id=( 
       select  Voucher_Id from @TempT where RowID=@i --)
        ......
    END
    

    更新 这是用于了解您发生了什么以及如何解决它的示例数据。

    declare @department table (deptid int, name varchar(50))
    declare @emp table (id int, name varchar(50), deptid int)
    
    insert into @department values (1,'d1'), (2,'d2'),(3,'d3'),(4,'d4')
    insert into @emp values(1,'ajay',1), (2,'ajay1',1),(3,'ajay3' ,2),(4,'ajay4' ,3),(5,'ajay5' ,4)
    
    
    select * from @department where deptid = 1
    
    /* suppose your sub-query like */
    --1. this give result
    select * from @department where deptid = (select deptid from @emp where id = 1)
    
    --2. this give result, but may be get wrong result as it take top 1.
    select * from @department where deptid = (select top 1 deptid from @emp )
    
    --3. this give error same you have
    select * from @department where deptid = (select deptid from @emp)
    
    --to resolve the above error, just uncomment below sub-query.
    --select deptid from @emp
    

    【讨论】:

    • 亲爱的,无论您的价值如何,您都可以直接在另一个窗口上运行。或者只是运行我的第二个选项,因为仅在 while 循环中添加选择查询。尝试给出或执行您在运行查询之前知道的一小部分结果,例如 @noofRows = 1 或给出 2
    【解决方案3】:

    我在这里看到以下查询因子查询返回多个值而失败的问题的答案:

    SET @Voucher_No = (SELECT [V_No] FROM @TempT WHERE [RowID] = @i);
    SET @Voucher_Type_No = (SELECT [voucher_type_no] FROM @TempT WHERE [RowID] = @i);
    SET @Voucher_Id = (SELECT [Voucher_Id] FROM @TempT WHERE [RowID] = @i);
    

    这些答案主要有两种建议的解决方案:

    1. SET @Variable = (SELECT TOP (1) [Field] FROM [Table] WHERE ...);,或
    2. SELECT @Variable = [Field] FROM [Table] WHERE ...);。

    令我惊讶的是,第二种方法被认为是首选方法。但是,有一些重要的事情需要考虑。

    首先:如果 SELECT 查询返回多个结果,@Variable 的值将成为查询结果集中最后检索到的值。指定 ORDER BY 子句时必须考虑这一点。

    所以下面的查询将返回5 而不是1:

    DECLARE @TempTable TABLE ([ID] INT);
    INSERT INTO @TempTable VALUES (1), (3), (2), (5), (4);
    
    DECLARE @Variable INT = 42;
    SELECT @Variable = [ID] FROM @TempTable ORDER BY [ID];
    
    SELECT @Variable AS [@Variable];
    

    第二:如果@Variable已经包含一个值并且SELECT查询没有产生任何结果(0行),@Variable的值保持不变!

    所以下面的查询将产生结果42 而不是NULL:

    DECLARE @TempTable TABLE ([ID] INT);
    INSERT INTO @TempTable VALUES (1), (3), (2), (5), (4);
    
    DECLARE @Variable INT = 42;
    SELECT @Variable = [ID] FROM @TempTable WHERE [ID] = 6;
    
    SELECT @Variable AS [@Variable];
    

    出于所有这些原因,我个人偏爱SET @Variable = (SELECT TOP (1) ...) 方法。

    【讨论】:

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