Динамическое изменение того, из какой таблицы выбирать, с помощью инструкции SQL CASE
-
20-08-2019 - |
Вопрос
Я пытаюсь написать хранимую процедуру, и в зависимости от определенного значения столбца я хочу иметь возможность изменять, из какой таблицы я выбираю.Я попытаюсь привести пример:
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, похоже, не нравится мой запрос, который я сконструировал.
Если кто-нибудь, кто видит, что я пытаюсь сделать, может предложить лучший способ сделать это, я был бы весь внимание :-)
Решение
Вы не можете использовать оператор 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'
Другие советы
Вы могли бы попробовать создать динамическую инструкцию SQL в виде строки, а затем вызвать хранимую процедуру sp_executesql для выполнения строки.
Видишь здесь для получения дополнительной информации и примеров.
Я не уверен , почему вы хотите что - то делать в одном операторе SQL ..Я не специалист по SQL Server, но в хранимой процедуре Oracle вы могли бы написать что-то вроде этого
If itemtype = 'A'
Then
<statement for table A>
Else
<statement for Table B>
End if
Что-то подобное должно работать и в SQL Server ..может быть, кто-нибудь мог бы подробнее рассказать об этом?
Ты действительно не объясняешь, где 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
Вам лучше использовать запрос ОБЪЕДИНЕНИЯ, чтобы сначала объединить таблицы, а затем ВЫБРАТЬ.
Кроме того, вы можете рассмотреть возможность создания представления для одной из таблиц, чтобы оно выводило только нужные вам столбцы при их переименовании, затем ОБЪЕДИНЯЛО, а затем выбирало из ОБЪЕДИНЕНИЯ.
Или используйте временную таблицу для хранения результата каждого запроса.Поместите создание временной таблицы в регистр (псевдокод, не тестировался):
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