Domanda

Sto cercando di scrivere una procedura memorizzata e, a seconda di un determinato valore di colonna, voglio poter cambiare la tabella da cui seleziono. Proverò a fare un esempio:

SELECT ItemNumber,
       ItemType, 
       Description
FROM

CASE ItemType
WHEN 'A' THEN TableA
ELSE TableB
END

WHERE 

CASE ItemType
WHEN 'A' THEN ItemNumber = @itemNumber
ELSE PartNumber = @itemNumber
END

Come puoi vedere, non solo sto cambiando dinamicamente la tabella da cui seleziono, ma poiché queste due tabelle sono state create in due momenti diversi da due persone diverse, anche i nomi delle colonne sono diversi.

Quindi, la mia domanda è: qual è il modo migliore per ottenere questo risultato, dato che a SQL Server non sembra piacere la mia query che ho creato.

Se qualcuno che vede quello che sto cercando di fare può suggerire un modo migliore per farlo, sarei tutto orecchi :-)

È stato utile?

Soluzione

Non è possibile utilizzare l'istruzione CASE nella clausola FROM, ma è invece possibile utilizzare quanto segue:

SELECT itemnumber, itemtype, description
  FROM tablea
 WHERE itemnumber = @itemnumber AND itemtype = 'A'
UNION ALL
SELECT itemnumber, itemtype, description
  FROM tableb
 WHERE partnumber = @itemnumber AND itemtype <> 'A'

Altri suggerimenti

Potresti provare a creare l'istruzione SQL dinamica come stringa e quindi chiamare la procedura memorizzata sp_executesql per eseguire la stringa.

Vedi qui per ulteriori informazioni ed esempi.

Non sono sicuro del motivo per cui vuoi fare le cose in una sola istruzione SQL .. Non sono una persona di SQL Server, ma in una procedura memorizzata Oracle potresti scrivere qualcosa del genere

If itemtype = 'A' 
Then 
 <statement for table A>
Else
 <statement for Table B>
End if

Qualcosa del genere dovrebbe funzionare anche in SQL Server .. forse qualcuno potrebbe espandersi su questo?

Non stai davvero spiegando da dove viene ItemType. Come suggerito UNION potrebbe essere applicabile se si stanno semplicemente combinando due tabelle.

Ecco un'altra possibilità che può riguardare il tuo problema:

SELECT ItemNumber,
       ItemType, 
       COALESCE(TableA.Description, TableB.Description) AS Description
FROM Items
LEFT JOIN TableA
    ON Items.ItemType = 'A'
    AND TableA.ItemNumber = Items.ItemNumber
LEFT JOIN TableB
    ON Items.ItemType <> 'A'
    AND TableB.ItemNumber = Items.ItemNumber

È meglio utilizzare la query UNION per unire prima le tabelle e poi SELEZIONARE.

Inoltre, potresti prendere in considerazione la possibilità di creare una vista per una delle tabelle, in modo da estrarre solo le colonne necessarie durante la ridenominazione, quindi UNION e quindi selezionare da UNION.

Oppure usa una tabella temporanea per memorizzare il risultato di ogni query. Metti la creazione della tabella temporanea in un CASE (pseudocodice, non testato):

CASE @itemType
   WHEN 'A'
      SELECT ACol1 AS Col1, ACol2 AS Col2
      FROM TABLE_A
      INTO #tempTable
      WHERE ItemNumber = @itemNumber
   ELSE
      SELECT BCol1 AS Col1, BCol2 AS Col2
      FROM TABLE_B
      INTO #tempTable
      WHERE PartNumber = @itemNumber
END

SELECT * FROM #tempTable
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top