Domanda

Sto creando una procedura memorizzata per restituire risultati di ricerca in cui alcuni parametri sono opzionali.

Voglio un'istruzione "quot" if nella mia clausola dove ma non riesco a farlo funzionare. La clausola dove dovrebbe filtrare solo per i parametri non nulli.

Ecco lo 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

Qualche idea su come farlo?

È stato utile?

Soluzione

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))

Altri suggerimenti

Abbiamo usato molto COALESCE qui in passato per " clausole WHERE dinamiche " come se stessi parlando.

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 '\')

Sorge un grosso problema quando si desidera filtrare facoltativamente una colonna che è anche nullable ... se i dati nella colonna sono null per una data riga E l'utente non ha inserito qualsiasi cosa cercare per quella colonna (quindi l'input dell'utente è anche null ), quindi quella riga non verrà nemmeno mostrata nei risultati (che, se i filtri sono facoltativo, comportamento di esclusione errato).

Al fine di compensare i campi nullable, si finisce per fare SQL in modo più appariscente in questo modo:

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))

Solo così capisci, IF è un codice procedurale in T-SQl. Non può essere utilizzato in un'istruzione insert / update / delete / select e può essere utilizzato solo per determinare quale delle due istruzioni si desidera eseguire. Quando sono necessarie diverse possibilità all'interno di un'istruzione, è possibile fare come sopra o utilizzare un'istruzione CASE.

Puoi anche usare la funzione 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)  

Questo fa la stessa cosa del suggerimento di Michael sopra ...

IsNull () e Coalesce () funzionano più o meno allo stesso modo, restituiscono il primo argomento non Null nell'elenco, tranne iSNull consente solo 2 argomenti e Coalesce può accettare qualsiasi numero ...

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

Prova a mettere l'istruzione IF attorno all'intera istruzione SQL. Ciò significa che avrà un'istruzione SQL per ogni condizione. Ha funzionato per me.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top