使用多行表功能或存储过程

时间:2011-08-09 15:23:17

标签: sql-server function ms-access stored-procedures

我正在重写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 个答案:

答案 0 :(得分:1)

性能在这个多语句UDF中将成为一个问题。

如果您从系统中读取的内容多于您编写的内容,我会尝试创建类似于以下内容的indexed view

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

如果您的系统是密集写入的话,我仍然会尝试这个,但是这个索引视图会减慢对其进行模式绑定的表的插入。索引视图确实需要付出代价,因此您只需创建普通视图即可获得良好的服务。