web-dev-qa-db-fra.com

La sous-requête a renvoyé plus d'une valeur, ce qui n'est pas autorisé lorsque la sous-requête suit =,! =, <, <=,>,> = Ou lorsque la sous-requête est utilisée comme expression

J'ai une procédure stockée qui select * from book table, en utilisant une sous-requête, ma requête est

USE [library]
GO

/****** Object:  StoredProcedure [dbo].[report_r_and_l]    Script Date: 04/17/2013 12:42:39 ******/

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

ALTER procedure [dbo].[report_r_and_l]
@fdate date,
@tdate date,
@key varchar(1)
as

if(@key='r')

    select * 
    from dbo.books 
    where isbn =(select isbn from dbo.lending where (act between @fdate and @tdate) and (stat ='close'))

else if(@key='l')

    select * 
    from dbo.books 
    where isbn =(select isbn from dbo.lending where lended_date between @fdate and @tdate)

Je sais que la sous-requête renvoie plus d'une requête à la requête principale, mais je ne sais pas comment éviter cette erreur, quelqu'un peut-il m'aider?

14
Roshan

Le problème est que ces deux requêtes renvoient chacune plus d'une ligne:

select isbn from dbo.lending where (act between @fdate and @tdate) and (stat ='close')
select isbn from dbo.lending where lended_date between @fdate and @tdate

Vous avez deux choix, selon le résultat souhaité. Vous pouvez soit remplacer les requêtes ci-dessus par quelque chose qui garantit de renvoyer une ligne nique (par exemple, en utilisant SELECT TOP 1), OR vous pouvez changer votre = à IN et renvoie plusieurs lignes, comme ceci:

select * from dbo.books where isbn IN (select isbn from dbo.lending where (act between @fdate and @tdate) and (stat ='close'))
24
Dan Puzey

Utilisez In au lieu de =

 select * from dbo.books
 where isbn in (select isbn from dbo.lending 
                where act between @fdate and @tdate
                and stat ='close'
               )

ou vous pouvez utiliser Exists

SELECT t1.*,t2.*
FROM  books   t1 
WHERE  EXISTS ( SELECT * FROM dbo.lending t2 WHERE t1.isbn = t2.isbn and
                t2.act between @fdate and @tdate and t2.stat ='close' )
9
praveen

Vous pouvez utiliser l'opérateur IN comme ci-dessous

select * from dbo.books where isbn IN
(select isbn from dbo.lending where lended_date between @fdate and @tdate)
4
bvr