Подзапрос в предложении IN (), вызывающий ошибку - PullRequest
0 голосов
/ 02 октября 2008

Я использую 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 на это ссылка MSDN.

Мой сохраненный код процедуры выглядит следующим образом. Я могу упростить это ради этого поста, если вы запросите так:

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, с которым сравнивается результат подзапроса.

Я не вижу причин, почему это не должно работать. Если у вас есть какие-либо подсказки, пожалуйста, дайте мне знать.

Ответы [ 3 ]

4 голосов
/ 02 октября 2008

Попробуйте переставить запрос так, чтобы логическое выражение находилось внутри подвыбора, например,

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
2 голосов
/ 02 октября 2008

Мне кажется, что это SELECT:

SELECT strSearchTypeCode FROM tblAdvanceSearchTypes

возвращает несколько строк, и это ваша проблема. Вы можете переписать его так:

SELECT TOP 1 strSearchTypeCode FROM tblAdvanceSearchTypes
2 голосов
/ 02 октября 2008

Я не знаю, что вы можете использовать оператор CASE внутри предложения IN, подобного этому. Я бы предложил переписать этот бит так:

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. Но я бы проверил план запросов просто для уверенности (доверяй, но проверяй).

...