Динамическое изменение таблицы для выбора с помощью оператора SQL CASE - PullRequest
8 голосов
/ 29 января 2009

Я пытаюсь написать хранимую процедуру и, в зависимости от определенного значения столбца, хочу иметь возможность изменить таблицу, из которой я выбираю. Я попробую привести пример:

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

Как видите, я не только динамически меняю таблицу, из которой выбираю, но и потому, что эти две таблицы были созданы в два разных времени двумя разными людьми, имена столбцов также различны.

Итак, мой вопрос: каков наилучший способ сделать это, поскольку SQL Server, похоже, не нравится мой запрос, который я построил.

Если кто-то, кто видит то, что я пытаюсь сделать, может предложить лучший способ сделать это, я был бы всем заинтересован: -)

Ответы [ 5 ]

5 голосов
/ 29 января 2009

Вы не можете использовать оператор CASE в предложении FROM, но вместо этого можете использовать следующее:

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'
4 голосов
/ 29 января 2009

Я не уверен, почему вы хотите сделать что-то в одном операторе SQL .. Я не человек SQL Server, но в хранимой процедуре Oracle вы могли бы написать что-то вроде этого

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

Нечто подобное должно работать и в SQL Server ... может быть, кто-то может расширить это?

4 голосов
/ 29 января 2009

Вы можете попробовать создать динамический оператор SQL в виде строки, а затем вызвать хранимую процедуру sp_executesql для выполнения строки.

См. здесь для получения дополнительной информации и примеров.

1 голос
/ 29 января 2009

Вы действительно не объясняете, откуда приходит ItemType. Как и предполагалось, UNION может быть применимо, если вы просто комбинируете две таблицы.

Вот еще одна возможность, которая может иметь отношение к вашей проблеме:

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
0 голосов
/ 29 января 2009

Лучше использовать запрос UNION для объединения таблиц, а затем SELECT.

Кроме того, вы можете рассмотреть возможность создания представления для одной из таблиц, поэтому при его переименовании он выбирает только нужные вам столбцы, затем UNION и затем выбирает из UNION.

Или используйте временную таблицу для хранения результатов каждого запроса. Поместите создание временной таблицы в CASE (псевдокод, не проверен):

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