Рефакторированная проекция SQL?
Мне не нравится, когда одна и та же вещь определяется в двух местах, если я могу избежать этого.
Я понимаю, что два запроса ниже имеют дело с двумя разными таблицами, но эти таблицы в основном содержат данные одного типа (разные предикаты требуют двух запросов), и я думаю о двух проекциях ниже, как о "одной и той же вещи, определенной в двух местах",
Когда / если я изменю эти запросы позже, чтобы включить другие столбцы, я уверен, что я всегда буду хотеть, чтобы прогнозы оставались идентичными.
Учитывая это, и без использования динамического SQL и без '*' в любой проекции (не разрешено в моей производственной среде), могу ли я один раз определить "набор столбцов" и использовать его в обоих запросах?
SELECT columnA
, columnB
, columnC
FROM Data
SELECT columnA
, columnB
, columnC
FROM DataArchive
4 ответа
Ваша база должна быть объединением Data и DataArchive и использовать встроенную табличную функцию (SQL Server 2005 и выше)?
CREATE FUNCTION UnifiedData (@LiveOnly bit, @ArchiveOnly bit)
RETURNS TABLE
AS
RETURN (
SELECT columnA
,columnB
,columnC
FROM (
SELECT 'Live' AS Src, *
FROM Data
WHERE @ArchiveOnly = 0
UNION ALL
SELECT 'Archive' AS Src, *
FROM DataArchive
WHERE @LiveOnly = 0
)
)
Не очень, но оптимизатор должен обрабатывать его довольно хорошо, поскольку он встроен.
Создайте представление Data UNION ALL DataArchive. Если позже вы сможете выполнить рефакторинг и объединить две таблицы, это будет прозрачно для ваших существующих запросов.
Я не могу придумать какой-либо эффективный способ сделать это. Вы могли бы, конечно, сделать вид с UNION ALL
из двух таблиц с добавлением столбца, который содержит имя таблицы в виде строки, затем выполните SELECT columnA, columnB, columnC FROM view WHERE table = 'Data'
но это похоже на довольно уродливый хак.
Да, SQL ужасен в этом смысле. Не существует универсального удовлетворительного способа сделать это. Вот пример использования синонимов:
if object_id('DataSynonym') is not null drop synonym DataSynonym
create synonym DataSynonym for Data
select columnA, columnB, columnC from DataSynonym
if object_id('DataSynonym') is not null drop synonym DataSynonym
create synonym DataSynonym for DataArchive
select columnA, columnB, columnC from DataSynonym
Проблема использования синонимов таким образом заключается в том, что они имеют глобальный охват. Если вы переопределите синоним на лету в одном соединении, это повлияет на пользователей во всех других соединениях.
Временные представления / функции или переменные представления / функции будут иметь большое значение для решения проблемы. Или макроязык, как то, что доступно в SAS.