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

Я работаю с приложением третьего уровня, где я не могу изменить таблицы. Мы создали пользовательские сопоставляемые таблицы «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 для выбора таблицы

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 ]

1 голос
/ 07 февраля 2009

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

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

1 голос
/ 07 февраля 2009

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

...