Использовать многострочную табличную функцию или хранимую процедуру - PullRequest
2 голосов
/ 09 августа 2011

Я переписываю базу данных Access, и у меня есть несколько ужасных запросов MS Access, которые мне нужно переписать.В основном они состоят из следующих настроек

SELECT *
FROM Query1, Query2, Query,...

. Эти запросы используются в 2 существующих базах данных и обычно состоят из подсчета / суммы данных.Затем мы используем итоги для отчетности.Большинство подзапросов такие же или что-то похожее

SELECT Count(Account), Reason, Sum(Amount)
FROM table1
GROUP BY Reason

Это достаточно легко переписать, и это не моя проблема.Моя проблема в том, что у меня есть около 20-30 таких запросов, которые нужно переписать.Один из запросов, которые теперь имеют пользователи, должен иметь возможность получить количество учетных записей, а также список учетных записей, составляющих общее количество.Так что теперь мои 20-30 запросов удваиваются, потому что они тоже хотят списки.

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

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

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

CREATE FUNCTION [udf_GeBreakdown]  
(
    @BusinessDate       datetime
    , @ListOfAccounts   bit
)
RETURNS @TableCount
TABLE 
(
    Account int, ReasonName varchar(50), Amount money
)
AS
BEGIN

    DECLARE @PreviousDate smalldatetime
    SET @PreviousDate = udf_GetNextImportDate(@BusinessDate, -1);

    IF @ListOfAccounts = 0
        BEGIN       
            INSERT INTO @TableCount
            SELECT Count(Account), R.ReasonName, Sum(Amount)
            FROM Debs.Resolved RS
            INNER JOIN Debs.Reason R
                ON RS.ReasonId = R.ReasonId
            WHERE RS.DebitDate = @PreviousDate
                AND RS.StatusId NOT IN (15, 17)
            GROUP BY R.ReasonName
        END
    ELSE
        BEGIN
            INSERT INTO @TableCount
            SELECT Account, R.ReasonName, Amount
            FROM Debs.Resolved RS
            INNER JOIN Debs.Reason R
                ON RS.ReasonId = R.ReasonId
            WHERE RS.DebitDate = @PreviousDate
                AND RS.StatusId NOT IN (15, 17)

        END

    RETURN 
END

Я не знаю, является ли это пустой тратой времени, делая это таким образом, или я должен просто предоставить список счетов, а затем получить свой счет / сумму, когда я запрашиваю это.Я ищу некоторую помощь и или руководство о том, как лучше поступить с этим.

1 Ответ

1 голос
/ 09 августа 2011

Производительность будет проблемой в этой UDF с несколькими утверждениями.

Если вы читаете из системы больше, чем пишете, я бы попытался создать индексированное представление , подобное следующему.

CREATE VIEW V1 WITH SCHEMABINDING AS
SELECT RS.DebitDate, Account, R.ReasonName, Amount
FROM Debs.Resolved RS
INNER JOIN Debs.Reason R
    ON RS.ReasonId = R.ReasonId
WHERE RS.StatusId NOT IN (15, 17)

CREATE INDEX X on V1 -- based on usage

Затем используйте следующую выписку в SP или отдельную выписку UDF, чтобы получить список счетов. Утверждение становится довольно тривиальным в этой точке. (здесь вам придется выполнить логику предыдущего дня ... не сохраняйте эту функцию в представлении)

SELECT Count(Account), ReasonName, Sum(Amount)
FROM V1 with(noexpand)
GROUP BY DebitDate, ReasonName  -- or use DebitDate in the where clause

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...