IN()子句中的子查询导致错误

问题描述:

我在SQL Server 2005上,并且遇到了一个我非常确定不应该得到的错误。IN()子句中的子查询导致错误

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

我下面就 this MSDN链接的例子·B。

我存储的proc代码如下。如果您要求这样我就可以把它简化为这篇文章的缘故:

ALTER PROCEDURE [dbo].[spGetSavedSearchesByAdminUser] 
    @strUserName varchar(50) 
    ,@bitQuickSearch bit = 0 
AS 

BEGIN 

    SELECT [intSearchID] ,strSearchTypeCode ,[strSearchName] 
    FROM [tblAdminSearches] 

    WHERE 
     strUserName = @strUserName 
     AND 
     strSearchTypeCode 
      IN (
       CASE @bitQuickSearch 
       WHEN 1 THEN 'Quick' 
       ELSE (SELECT strSearchTypeCode FROM tblAdvanceSearchTypes) 
       END 
      ) 

    ORDER BY strSearchName 
END 

我已签有来自子查询结果集和strSearchTypeCode子查询结果相比较之间没有数据类型不匹配。

我看不出为什么这不应该工作。如果你有任何线索,请让我知道。

尝试重新排列查询,以便布尔表达式在子查询内发生,例如,

ALTER PROCEDURE [dbo].[spGetSavedSearchesByAdminUser] 
    @strUserName varchar(50) 
    ,@bitQuickSearch bit = 0 
AS 

BEGIN 

    SELECT [intSearchID] ,strSearchTypeCode ,[strSearchName] 
    FROM [tblAdminSearches] 

    WHERE 
     strUserName = @strUserName 
     AND 
     strSearchTypeCode 
       IN (SELECT strSearchTypeCode FROM tblAdvanceSearchTypes where @bitQuickSearch=0 
        UNION 
        SELECT 'Quick' AS strSearchTypeCode WHERE @bitQuickSearch=1) 

    ORDER BY strSearchName 
END 
+0

我会做一个联盟所有,因为即使你有愚蠢,它在IN子句中并不重要。 – 2008-10-02 16:47:05

我不知道你可以像这样在IN子句中使用CASE语句。我建议重写该位:

WHERE strUserName = @strUserName AND (
    (@bitQuickSearch = 1 AND strSearchTypeCode = 'Quick') 
    OR 
    (strSearchTypeCode IN (SELECT strSearchTypeCode FROM tblAdvanceSearchTypes)) 
) 

或者,如果你真的喜欢的风格你到了那里:

WHERE strUserName = @strUserName 
    AND strSearchTypeCode IN (
     SELECT CASE @bitQuickSearch WHEN 1 THEN 'Quick' ELSE strSearchTypeCode END 
     FROM tblAdvanceSearchTypes 
    ) 

一般情况下,SQL应该是明智的足够聪明,优化掉的表如果@bitQuickSearch = 1。但是,我会检查查询计划,以确保(信任,但验证)。

在我看来,这个选择:

SELECT strSearchTypeCode FROM tblAdvanceSearchTypes 

返回多行,那是你的问题。您可以将其重写为:

SELECT TOP 1 strSearchTypeCode FROM tblAdvanceSearchTypes