子查询返回了多个值错误

时间:2015-01-19 06:38:27

标签: sql sql-server tsql

我正在使用以下查询,但它正在抛出错误。它适用于某些场景,具体取决于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

3 个答案:

答案 0 :(得分:0)

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

您必须使用TOP关键字修改您的子查询,或者给出过滤器(其中包括条件和排序)更多只返回一个值。

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

答案 1 :(得分:0)

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

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 :(得分:0)

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

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的值将成为从查询结果集中检索到的 last 值。指定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) ...)方法。