Объедините или используйте логику управления потоком для определения таблицы, для которой нужно составить отчет

Я работаю с приложением третьего уровня, где я не могу изменить таблицы. Мы создали пользовательские сопоставляемые таблицы "Monthly" с дополнительным столбцом datetime "AsOfDate", в который мы выгружаем данные в конце месяца и помечаем эти данные датой последнего дня месяца.

Я хочу иметь возможность создавать одну хранимую процедуру (приложение разработано так, чтобы требовать представления или хранимой процедуры в качестве источника всех отчетов.) И использовать параметр, который будет использовать либо текущую таблицу данных (параметр может иметь значение NULL или = сегодняшние Дата) или используйте таблицу окончания месяца и отфильтруйте по дате окончания месяца. Таким образом, у меня есть один отчет, в котором пользователь может использовать текущий или данные за определенный конец месяца.

Что бы вы предпочли (и почему) Извините, это не полностью закодировано

Решение № 1 Union Query

Create Proc Balance_Report (@AsOfDate)
AS

Select Column1
From
    (Select GetDate() as AsOfDate
       , Column1 
     From Current.Balance
    Union 
    Select AsOfDate
       , Column1 From MonthEnd.Balance
    ) AS All_Balances
Where All_Balances.AsOfDate = @AsOfDate

Решение № 2 Используйте If Statement для выбора таблицы

Create Proc Balance_Report (@AsOfDate)
AS

If @AsOfDate IS NULL or @AsOfDate = GetDate()
   Select GetDate() as AsOfDate
       , Column1 
     From Current.Balance
Else
    Select AsOfDate
       , Column1 From MonthEnd.Balance
    Where AsOfDate = @AsOfDate

Опять же, это не полностью закодировано и является своего рода независимым от БД (но это SQL Server 2005).

Редактировать: вариант решения № 2 с использованием отдельных хранимых процедур

Create Proc Balance_Report (@AsOfDate)
AS

If @AsOfDate IS NULL or @AsOfDate = GetDate()
   Exec Current_Balance_Date -- no param necessary
Else
    exec MonthEnd_Balance_Date @AsOfDate

2 ответа

Решение

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

Однако следует помнить одну вещь: если вы используете второй метод, обязательно пометьте свою хранимую процедуру как WITH (RECOMPILE) (я не могу вспомнить, требуются ли скобки или нет - проверьте синтаксис). Таким образом, оптимизатор создаст новый план запроса, основанный на том, какая ветвь оператора IF должна быть выполнена.

Я предпочитаю решение без объединения. Выбор из одной таблицы всегда будет быстрее, чем объединение и выбор данных одной таблицы из объединения.

Другие вопросы по тегам