Pregunta

Estoy tratando de escribir un procedimiento almacenado y, dependiendo de un cierto valor de columna, quiero poder cambiar la tabla de la que selecciono. Trataré de dar un ejemplo:

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

Como puede ver, no solo estoy cambiando dinámicamente la tabla que selecciono, sino que dado que estas dos tablas fueron hechas en dos momentos diferentes por dos personas diferentes, los nombres de las columnas también son diferentes.

Entonces, mi pregunta es: ¿Cuál es la mejor manera de lograr esto, ya que a SQL Server no parece gustarle mi consulta que he construido?

Si alguien que ve lo que estoy tratando de hacer puede sugerir una mejor manera de hacerlo, sería todo oídos :-)

¿Fue útil?

Solución

No puede usar la declaración CASE en la cláusula FROM, pero puede usar lo siguiente en su lugar:

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'

Otros consejos

Puede intentar crear la instrucción SQL dinámica como una cadena y luego llamar al procedimiento almacenado sp_executesql para ejecutar la cadena.

Consulte aquí para obtener más información y ejemplos.

No estoy seguro de por qué quiere hacer cosas en una declaración SQL. No soy una persona de SQL Server, pero en un procedimiento almacenado de Oracle podría escribir algo como esto

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

Algo como esto también debería funcionar en SQL Server ... ¿tal vez alguien podría ampliar esto?

Realmente no estás explicando de dónde viene ItemType. Como se sugiere, UNION podría ser aplicable si simplemente combina dos tablas.

Aquí hay otra posibilidad que puede estar relacionada con su 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

Es mejor utilizar la consulta UNION para unir primero las tablas y luego SELECCIONAR.

Además, puede considerar crear una vista para una de las tablas, de modo que extraiga solo las columnas que necesita mientras las renombra, luego UNION y luego seleccione desde UNION.

O use una tabla temporal para almacenar el resultado de cada consulta. Ponga la creación de la tabla temporal en un CASO (pseudocódigo, no probado):

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
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top