Pregunta

Estoy en SQL Server 2005 y recibo un error que estoy bastante seguro de que no debería estar recibiendo.

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.

Estoy siguiendo el ejemplo # B en este enlace de MSDN.

Mi código de proceso almacenado es el siguiente. Puedo simplificarlo por el bien de esta publicación si así lo solicita:

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

He comprobado que no hay una falta de coincidencia en el tipo de datos entre el conjunto de resultados de la subconsulta y el strSearchTypeCode con el que se compara el resultado de la subconsulta.

No veo ninguna razón por la que esto no debería funcionar. Si tiene alguna pista, hágamelo saber.

¿Fue útil?

Solución

Intente reorganizar la consulta para que la expresión booleana aparezca dentro de la subselección, por ejemplo,

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

Otros consejos

No sé si puede usar la sentencia CASE dentro de una cláusula IN de esa manera. Sugeriría reescribir ese bit a:

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

o, si realmente te gusta el estilo que tienes ahí:

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

En general, SQL debería ser lo suficientemente inteligente como para optimizar la tabla si @bitQuickSearch = 1. Pero, verificaría el plan de consulta solo para estar seguro (confianza, pero verificación).

Me parece que este SELECCIONAR:

SELECT strSearchTypeCode FROM tblAdvanceSearchTypes

devuelve múltiples filas, y ese es tu problema. Puedes reescribirlo para que sea:

SELECT TOP 1 strSearchTypeCode FROM tblAdvanceSearchTypes
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top