【问题标题】:Subquery in an IN() clause causing errorIN() 子句中的子查询导致错误
【发布时间】:2010-09-14 20:51:58
【问题描述】:

我使用的是 SQL Server 2005,但我遇到了一个我很确定不应该遇到的错误。

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.

我按照例子#B on thisMSDN 链接。

我的存储过程代码如下。如果您要求,我可以为这篇文章简化它:

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 之间没有数据类型不匹配。

我看不出为什么这不起作用。如果您有任何线索,请告诉我。

【问题讨论】:

    标签: sql-server subquery in-clause


    【解决方案1】:

    尝试重新排列查询,使布尔表达式出现在子选择中,例如

    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
    

    【讨论】:

    • 我会把它设为 UNION ALL,因为即使你有骗子,在 IN 子句中也没关系。
    【解决方案2】:

    在我看来,这个 SELECT:

    SELECT strSearchTypeCode FROM tblAdvanceSearchTypes
    

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

    SELECT TOP 1 strSearchTypeCode FROM tblAdvanceSearchTypes
    

    【讨论】:

      【解决方案3】:

      我不知道您可以在这样的 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
         )
      

      一般来说,如果@bitQuickSearch = 1,SQL 应该足够智能以优化表。但是,我会检查查询计划以确保(信任,但要验证)。

      【讨论】:

        猜你喜欢
        • 2019-04-18
        • 2012-04-24
        • 1970-01-01
        • 2021-01-29
        • 1970-01-01
        • 2016-02-14
        • 2020-11-12
        • 2017-05-24
        • 1970-01-01
        相关资源
        最近更新 更多