Domanda

Ho letto sull'uso dell'espressione CASE all'interno della clausola WHERE qui:

http: // scottelkin. com / sql / con-a-caso-dichiarazione-in-a-sql-dove-clausola /

Sto cercando di utilizzare questo per filtrare i risultati dalla mia dichiarazione selezionata, in base a un numero di contratto che verrà passato dall'applicazione dell'utente. Il mio codice attualmente genera un errore di "Parametro non valido", indipendentemente da ciò che viene passato. Ho verificato che SELECT / FROM funziona correttamente, come in una clausola WHERE senza un'espressione CASE. Ecco il mio codice.

WHERE     (CASE WHEN @ContractNo = 0 THEN @ContractNo ELSE @ContractNo END =
tblContracts.ContractNo)

La ridondanza del codice è a scopo di risoluzione dei problemi, sto pianificando di utilizzare il filtro jolly sul CASE in seguito. Mi sto concentrando su come abbassare la sintassi in questo momento. Credo che questo dovrebbe restituire tutti i record per i quali il parametro corrisponde al numero di contratto memorizzato nella tabella. Qualsiasi aiuto o consiglio sarebbe molto apprezzato.

È stato utile?

Soluzione

Dopo aver letto la tua spiegazione, c'è un modo migliore per farlo senza CASE :

WHERE @ContractNo = 0 OR tblContracts.ContractNo = @ContractNo

Questo restituirà solo i numeri di contratto corrispondenti, a meno che @ContractNo sia 0, nel qual caso restituirà tutti i record.

Modifica: ho appena notato che casperOne ha proposto la stessa cosa . Non l'ho visto. Cresci da soli.

Altri suggerimenti

Sei sicuro di voler fare questo? L'istruzione case restituisce SEMPRE @ContractNo . Penso che quello che stai cercando sia questo:

where 
    case @ContractNo 
        when 0 then tblContracts.ContractNo 
        else @ContractNo 
    end = tblContracts.ContractNo

Il filtro sopra dice " dammi il contratto in cui ContractNo è uguale al parametro, o tutti loro se il parametro è 0.

Il filtro precedente ha filtrato solo dove il campo del numero di contratto è esattamente uguale al parametro.

Indipendentemente da ciò, dovresti invece farlo:

where @ContractNo = 0 or @ContractNo = tblContracts.ContractNo

La logica è molto più facile da capire, e soprattutto (non citarmi su questo), l'ottimizzatore probabilmente funzionerà meglio al di fuori dell'istruzione case.

Prova a tralasciare le parentesi che si trovano comunque nel posto sbagliato - quella giusta dovrebbe essere dopo "END".

Forse hai dimenticato di dichiarare @ContractNo? È paragonabile a 0 e a tblContracts.ContractNo?

Il post di Recursive ha risolto il mio problema con precisione.

Ho visto lamentele sulla chiarezza del mio post originale. In futuro, cosa posso fare per rendere più semplice ciò che sto dicendo? Non sono abituato a formulare domande sul codice e mi scuso per le cose confuse che aveva. Ho solo bisogno di fornire i dettagli estesi come nel mio secondo post?

Grazie ancora per tutto l'aiuto.

Sposta la parentesi chiusa prima del = in questo modo:

WHERE     (CASE WHEN @ContractNo = 0 THEN @ContractNo ELSE @ContractNo END)=tblContracts.ContractNo

Non riesco a vedere cosa farà questa dichiarazione del caso ... stai restituendo la stessa cosa nel caso in cui @ContractNo = 0 o se non lo è ...

La sintassi corretta è:

  Select...
  ...
  Where(
    Case
      When <Condition>
        Then <Return if true>
        Else <Return if false>
      End
 ) = <Whatever is being matched to the output of the case statement>

Indipendentemente dalla sintassi, il tuo esempio non ha molto senso, se stai cercando tutti gli articoli che corrispondono o hanno un numero di contratto pari a 0, allora dovresti:

Select...
...
Where (
  @ContractNo = 0 Or
  @ContractNo = tblContracts.ContractNo
)

Il che sembra avere molto più senso di quello per cui stai tentando di utilizzare l'istruzione case.

Modifica: Devo aver letto male la domanda: il parametro mancante di solito significa che il parametro (in questo caso @ContractNo) non è dichiarato nell'ambito della tua query / procedura. Ma qualcuno l'ha già sottolineato, quindi non posso prendermi il merito.

Il motivo dell'istruzione case, incluso l'intero " Se è 0, indica il parametro e, in caso contrario, fornisci semplicemente il parametro " è stato testarlo per cercare di ottenere la sintassi corretta. Inizialmente, avevo provato a dire " Se è 0, passa '%', per restituire ogni valore. Il codice che ho inserito era perché continuavo a ricevere "Parametro non valido" e immaginavo che ci fosse qualcosa di sbagliato nella mia sintassi. Quando l'ho separato in corrispondenza dei parametri di base in questo modo,

WHERE @ContractNo = tblContracts.ContractNo

ha restituito i record benissimo. Lasciami spiegare un po 'di più.

Sto estraendo da un sacco di tabelle diverse e filtrando il contenuto con informazioni non incluse nell'istruzione select (cioè tblContracts non ha informazioni estratte da Select, è usato solo in Where). L'utente selezionerà da una casella combinata che avrà i diversi numeri di contratto, nonché un valore predefinito di "Tutti".

Avrò un evento per quando cambia l'indice della casella combinata. Se è "All", 0 verrà passato come parametro e non voglio che il filtro venga eseguito. Altrimenti, voglio solo le informazioni per quel numero di contratto (il motivo di Else @ContractNo).

Non intendi qualcosa del genere?

SELECT * 
    FROM tblContracts
    WHERE     
    CASE 
       WHEN tblContracts.ContractNo = 0 THEN @ContractNo 
       ELSE tblContracts.ContractNo
    END = tblContracts.ContractNo

Dove @ContractNo è una variabile dello stesso tipo di dati di tblContracts.ContractNo

Perché hai persino bisogno di un'istruzione case?

QUANDO @ContractNo = 0 allora (0 = tblContracts.ContractNo) else @ContractNo quindi (@ContractNo = tblContracts.ContractNo)

Questo non ha senso dal momento che potresti semplicemente scrivere questo come

Dove @contractNo = tblContracts.contractNo

Il numero del contratto è in realtà un numero o è una stringa che risulta essere sempre un numero. Controlla i tipi di dati tra la tabella e il parametro e l'istruzione CASE (ad esempio, " = 0 " o " = '0' ")

Questa sintassi dovrebbe funzionare (funziona in Oracle)

WHERE CASE WHEN tblContracts.ContractNo = 0 
           THEN @ContractNo 
           ELSE tblContracts.ContractNo
      END = tblContracts.ContractNo

quando dici:

  

Sto estraendo da un sacco di tabelle diverse e filtrando il contenuto con informazioni non incluse nell'istruzione select (ovvero tblContracts non ha informazioni estratte da Select, viene utilizzato solo in Where). L'utente selezionerà da una casella combinata che avrà i diversi numeri di contratto, nonché un valore predefinito di "Tutti".

Quindi mi sembra che dovrebbe avere un " Dov'è " clausola. dal momento che non stai estraendo alcuna informazione da quel tavolo ?!

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