Eseguire comando diverso rispetto a una variabile

di il
17 risposte

Eseguire comando diverso rispetto a una variabile

Buongiorno a tutti, avrei questa necessità:
su questa query (semplificata):

declare @x as varchar
set @x=2

select *
from <tabella>
where
......

avrei bisogno di eseguire il where con la condizione <campo> like '%' se @x=0 oppure <campo> in @x se il valore è diverso da 0.
Esiste un modo per farlo?

Grazie

17 Risposte

  • Re: Eseguire comando diverso rispetto a una variabile

    kkzan ha scritto:


    avrei bisogno di eseguire il where con la condizione <campo> like '%' se @x=0 oppure <campo> in @x se il valore è diverso da 0.
    Se non riesci a integrare direttamente la condizione nella WHERE usando gli operatori logici AND e OR con le relative parentesi, puoi ricorrere all'uso di un IF (vedi qualche esempio).

    Ciao!
  • Re: Eseguire comando diverso rispetto a una variabile

    Ok l'if, ma il mio problema è creare la condizione in un caso usando 'like' e nel secondo caso usando 'in'; provo a spiegarmi meglio:
    dovrebbe essere con questa logica

    if @x=0
    where <campo> like '%'
    else
    where <campo> in @x
    end

    ma una istruzione scritta così non può funzionare
  • Re: Eseguire comando diverso rispetto a una variabile

    Mi viene in mente qualcosa del tipo
    
    if @x=0
      select * from tabella where <campo> like '%'
    else
      select * from tabella where <campo> in @x
    
  • Re: Eseguire comando diverso rispetto a una variabile

    Ah ok, giusto!
    non so perché pensavo di cambiare solo la condizione.....
    grazie 1000
  • Re: Eseguire comando diverso rispetto a una variabile

    Io valuterei anche
    
    SELECT *
    FROM Tabella
    WHERE (@x=0 AND <campo> LIKE '%')
       OR (@x!=0 AND <campo> IN @x)
    Così il blocco della SELECT...FROM viene scritto una volta sola...
    Onestamente non saprei quale possa essere la soluzione più efficiente, ma un paio di piani di esecuzione e il gioco è fatto...
  • Re: Eseguire comando diverso rispetto a una variabile

    Grazie proverò anche questo!
  • Re: Eseguire comando diverso rispetto a una variabile

    Confermo che l'ultimo esempio è quello che uso anche io in questi casi.
  • Re: Eseguire comando diverso rispetto a una variabile

    Salve a Tutti,

    tendenzialmente quanto riportato da @Sgrubak dovrebbe generare i piani migliori, ANCHE SE, purtroppo, il caching del piano di esecuzione puo' fortemente penalizzare le situazioni nel branch di codice "alternativo" ... quindi se la prima esecuzione di
    @x = 0 quindi
    if @x=0
    select * from tabella where <campo> like '%'

    else
    select * from tabella where <campo> in @x

    genera un piano di esecuzione ottimale per where <campo> like '%',
    la seconda esecuzione con @x <> 0 potrebbe incorrere in forti penalizzazioni visto che verra' eseguito tutt'altro filtro...
    quindi, in caso di utilizzo di questa modalita' consiglierei l'impostazione di WITH RECOMPILE nel caso di stored procedure, che vanifica ovviamente molte ottimizzazioni MA sicuramente non fa incorrere in problematiche di piani di esecuzione non corretti ...

    salutoni romagnoli

    Andrea
  • Re: Eseguire comando diverso rispetto a una variabile

    asql ha scritto:


    Salve a Tutti,

    tendenzialmente quanto riportato da @Sgrubak dovrebbe generare i piani migliori, ANCHE SE, purtroppo, il caching del piano di esecuzione puo' fortemente penalizzare le situazioni nel branch di codice "alternativo" ... quindi se la prima esecuzione di
    @x = 0 quindi
    if @x=0
    select * from tabella where <campo> like '%'

    else
    select * from tabella where <campo> in @x

    genera un piano di esecuzione ottimale per where <campo> like '%',
    la seconda esecuzione con @x <> 0 potrebbe incorrere in forti penalizzazioni visto che verra' eseguito tutt'altro filtro...
    quindi, in caso di utilizzo di questa modalita' consiglierei l'impostazione di WITH RECOMPILE nel caso di stored procedure, che vanifica ovviamente molte ottimizzazioni MA sicuramente non fa incorrere in problematiche di piani di esecuzione non corretti ...

    salutoni romagnoli

    Andrea
    ciao Andrea,

    e se si facesse così chiamando altre due stored a seconda del valore di @x ?
    
    if @x=0
         exec  dbo.spExecSelectWhereLike ....
    else
        exec  dbo.spExecSelectWhereLikeIn ...
    
  • Re: Eseguire comando diverso rispetto a una variabile

    Così triplichi il numero di stored procedure necessarie.
  • Re: Eseguire comando diverso rispetto a una variabile

    Sinceramente starei sulla prima risposta che ti hanno dato, ovvero:
    
    SELECT *
    FROM Tabella
    WHERE (@x=0 AND <campo> LIKE '%')
       OR (@x!=0 AND <campo> IN @x)
    
    Se poi incappi nel problema di performance che hanno segnalato (e ci può stare), puoi aggiungere l'opzione "RECOMPILE" in modo da far studiare al DB un nuovo piano di esecuzione.

    In questo caso paghi sempre lo scotto dello studio del piano di esecuzione migliore, però eviti di incappare nel problema segnalato
  • Re: Eseguire comando diverso rispetto a una variabile

    Toki ha scritto:


    Così triplichi il numero di stored procedure necessarie.
    vero .... ma in fondo mica devi portarle sulle spalle le stored

    Personalmente in caso di stored molto usata e pesante con l'altro metodo un pensierino ce lo farei
  • Re: Eseguire comando diverso rispetto a una variabile

    Salve,

    PiGi78 ha scritto:


    Sinceramente starei sulla prima risposta che ti hanno dato, ovvero:
    
    SELECT *
    FROM Tabella
    WHERE (@x=0 AND <campo> LIKE '%')
       OR (@x!=0 AND <campo> IN @x)
    
    Se poi incappi nel problema di performance che hanno segnalato (e ci può stare), puoi aggiungere l'opzione "RECOMPILE" in modo da far studiare al DB un nuovo piano di esecuzione.

    In questo caso paghi sempre lo scotto dello studio del piano di esecuzione migliore, però eviti di incappare nel problema segnalato
    qui il problema del RECOMPILE "non serve e non aiuta"... il solo fatto dell'OR implica piani NON ottimali in se', al di la' del sicuro utilizzo di SQL Server della short circuit evaluation...
    il RECOMPILE puo' "aiutare" nel caso
    IF @x > 0
    SELECT a
    ELSE
    SELECT b

    dove i il branch di codice eseguito varia completamente per il batch in corso... nel caso di sopra, invece l'OR non richiede un RECOMPILE in quanto comunque il piano generato NON sara' ottimale...

    il "modo piu'" valido, in questo senso, e' "esterno" al chiamante...
    cioe' che il client esterno, in base al valore "esterno" di @x, chiami la stored procedure A oppure B... ma questo sposta molto il lavoro di logica lato client...
    quindi il secondo modo ottimale e' il branching interno alla stored procedure primaria come indicato da @sspintux,
    if @x=0
    exec dbo.spExecSelectWhereLike ....
    else
    exec dbo.spExecSelectWhereLikeIn ...

    MA, e c'e' sempre un ma , c'e' il maggior "costo" di manutenzione di 3 stored procedures, come giustamente indica @Toki

    nella pratica, se non fortemente penalizzante, e' uso comune il
    WHERE (@x=0 AND <campo> LIKE '%')
    OR (@x!=0 AND <campo> IN @x)

    ma un giro di test (e non con il db di sviluppo) ce lo farei

    ad ogni modo "ho visto cose che...", dove queste sottigliezze sono da considerarsi molto marginali

    salutoni romagnoli
    --
    Andrea
  • Re: Eseguire comando diverso rispetto a una variabile

    sspintux ha scritto:


    Toki ha scritto:


    Così triplichi il numero di stored procedure necessarie.
    vero .... ma in fondo mica devi portarle sulle spalle le stored
    Prova a mettere mano a database con 300 stored procedure non documentate , poi capirai meglio la necessità di non far proliferare "cose" se non strettamente necessario.
    Creare 3 stored procedure per gestire una where condition possiamo farlo rientrare nel magico mondo degli antipatterns.

    Questione performance: c'è davvero una questione di performance su questa ricerca? quanti records ci sono in questa tabella?
Devi accedere o registrarti per scrivere nel forum
17 risposte