Pregunta

Estoy creando un procedimiento almacenado para devolver resultados de búsqueda donde algunos de los parámetros son opcionales.

Quiero una declaración "si" en mi cláusula where pero no puedo hacer que funcione. La cláusula where debe filtrar solo por los parámetros no nulos.

Aquí está la sp

ALTER PROCEDURE spVillaGet 
-- Add the parameters for the stored procedure here
@accomodationFK int = null,
@regionFK int = null,
@arrivalDate datetime,
@numberOfNights int,
@sleeps int = null,
@priceFloor money = null,
@priceCeil money = null
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;

-- Insert statements for procedure here
select tblVillas.*, tblWeeklyPrices.price from tblVillas
INNER JOIN tblWeeklyPrices on tblVillas.villaId = tblWeeklyPrices.villaFK
where 
    If @accomodationFK <> null then
        accomodationTypeFK = @accomodationFK 
     @regionFK <> null Then
        And regionFK = @regionFK 
    IF @sleeps <> null Then
        And sleeps = @sleeps 
    IF @priceFloor <> null Then
        And price >= @priceFloor And price <= @priceCeil


END

¿Alguna idea de cómo hacer esto?

¿Fue útil?

Solución

select tblVillas.*, tblWeeklyPrices.price 
from tblVillas
INNER JOIN tblWeeklyPrices on tblVillas.villaId = tblWeeklyPrices.villaFK
where (@accomodationFK IS null OR accomodationTypeFK = @accomodationFK)
  AND (@regionFK IS null or regionFK = @regionFK)
  AND (@sleeps IS null OR sleeps = @sleeps)
  AND (@priceFloor IS null OR (price BETWEEN @priceFloor And @priceCeil))

Otros consejos

Hemos usado mucho COALESCE aquí en el pasado para " cláusulas dinámicas WHERE " como si estuvieras hablando.

SELECT *
FROM  vehicles
WHERE ([vin]   LIKE COALESCE(@vin, [vin])     + '%' ESCAPE '\')
  AND ([year]  LIKE COALESCE(@year, [year])   + '%' ESCAPE '\')
  AND ([make]  LIKE COALESCE(@make, [make])   + '%' ESCAPE '\')
  AND ([model] LIKE COALESCE(@model, [model]) + '%' ESCAPE '\')

Sin embargo, surge un gran problema cuando desea filtrar opcionalmente una columna que también es anulable ... si los datos en la columna son null para una fila dada Y el usuario no ingresó cualquier cosa para buscar esa columna (por lo que la entrada del usuario también es null ), entonces esa fila ni siquiera aparecerá en los resultados (que, si sus filtros son opcional, es un comportamiento de exclusión incorrecto).

Para compensar los campos anulables, termina teniendo que hacer un SQL de aspecto más desordenado de la siguiente manera:

SELECT *
FROM  vehicles
WHERE (([vin]   LIKE COALESCE(@vin, [vin])     + '%' ESCAPE '\')
       OR (@vin IS NULL AND [vin] IS NULL))
  AND (([year]  LIKE COALESCE(@year, [year])   + '%' ESCAPE '\')
       OR (@year IS NULL AND [year] IS NULL))
  AND (([make]  LIKE COALESCE(@make, [make])   + '%' ESCAPE '\')
       OR (@make IS NULL AND [make] IS NULL))
  AND (([model] LIKE COALESCE(@model, [model]) + '%' ESCAPE '\')
       OR (@model IS NULL AND [model] IS NULL))

Para que lo entiendas, IF es un código de procedimiento en T-SQl. No se puede usar en una declaración de inserción / actualización / eliminación / selección, solo se puede usar para determinar cuál de las dos declaraciones desea ejecutar. Cuando necesite diferentes posibilidades dentro de una declaración, puede hacer lo anterior o usar una declaración CASE.

También puede usar la función IsNull o Coalesce

Where accomodationTypeFK = IsNull(@accomodationFK, accomodationTypeFK)
    And regionFK = Coalesce(@regionFK,regionFK)
    And sleeps = IsNull(@sleeps,sleeps ) 
    And price Between IsNull(@priceFloor, Price) And IsNull(priceCeil, Price)  

Esto hace lo mismo que la sugerencia anterior de Michael ...

IsNull () y Coalesce () funcionan más o menos de la misma manera, devuelven el primer argumento no nulo en la lista, excepto que iSNull solo permite 2 argumentos y Coalesce puede tomar cualquier número ...

http: / /blogs.msdn.com/sqltips/archive/2008/06/26/differences-between-isnull-and-coalesce.aspx

Intente colocar su declaración IF alrededor de toda la declaración SQL. Eso significa que tendrá una instrucción SQL para cada condición. Eso funcionó para mí.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top