如何在SQL Server中使用表值函数

时间:2011-05-17 06:54:15

标签: sql-server tsql stored-procedures user-defined-functions

我在这里有一个存储过程

ALTER PROCEDURE [dbo].[SortedReport]
(
    @ClientID INT,
    @RecordLimit,
    @FromDate DATETIME,
    @ToDate DATETIME,
    @OrderBy NVARCHAR(MAX)
)
AS
BEGIN
SELECT TOP (@RecordLimit) 
        sv.ClientID,
        sv.VendorID,
        sv.ProductID,
        sv.TransactionTime,
        sv.ClientName,
        sv.VendorName,
        sv.ProductName,
        sv.ProductCode,
        sv.VendorCode,
        StockCount = dbo.GetStockCount(sv.ProductID, sv.VendorID, @ClientID, @FromDate, @ToDate),
        TransactionCount = dbo.GetTransCount(sv.ProductID, sv.VendorID, @FromDate, @ToDate),
        ProductCount     = dbo.GetProductCount(sv.ProductID, sv.VendorID),
FROM SortedReportiew AS sv 
WHERE (sv.ClientID = @ClientID)
    AND (sv.TransactionTime >= @FromDate)
    AND (sv.TransactionTime < @Date)

当我有大数据时,SELECT部分​​中的函数调用非常低效。有100行的函数调用意味着很多读取。

我需要从那里删除调用并在表值函数中进行批量读取并将大多数报表参数传递给这些函数

SELECT 
    sd.StockCount,
    sd.TransactionCount 
    pd.ProductCount,
    TransactionTime,
    ClientName,
    VendorName,
    ProductName,
    ProductCode,
    VendorCode
FROM 
( 
    SELECT TOP (@RecordLimit) 
        sv.ClientID,
        sv.VendorID,
        sv.ProductID,
        sv.TransactionTime,
        sv.ClientName,
        sv.VendorName,
        sv.ProductName,
        sv.ProductCode,
        sv.VendorCode
    FROM SortedReportiew AS sv 
        --Begin Where {
    WHERE 
        (ClientID = @ClientID) 
        AND TransactionTime >= @FromDate 
        AND TransactionTime < @ToDate 
        --End Where }
) AS mainQuery 
FULL JOIN GetStockDetails( 
     @ClientID,
     @FromDate,
     @ToDate, 
     ) AS sd 
ON mainQuery.ClientID = sd.ClientID
LEFT OUTER JOIN GetProductDetails( 
     @ProductID 
     @FromDate,
     @ToDate,
     ) AS pd 
ON mainQuery.ClientID = pd.ClientID

之前我没有尝试过表值函数。我到目前为止所写的是

ALTER FUNCTION [dbo].[GetStockDetails] 
(
   @ClientID INT
   @FromDate DATETIME,
   @ToDate DATETIME,
)
RETURNS @tblStockDetails TABLE (
  -- Columns returned by the function
        StockCount INT,
        TransactionCount  INT
)
AS

BEGIN

INSERT INTO @tblStockDetails

SELECT 
    StockCount,
    TransactionCount
FROM
(
SELECT 
    StockCount = (SELECT COUNT(*)... //  My Query here
    ....
RETURN

END

有人可以就此要求的表值函数的格式提出建议。

1 个答案:

答案 0 :(得分:4)

回答上述评论。

好吧,你应该让临时表变得如此之大,以至于你有所有不是常量的条目(行)。并使用常量@fromDate@toDate

限制表格

例如:

dbo.GetStockCount(sv.ProductID, sv.VendorID, @ClientID, @FromDate, @ToDate)

这应该是这样的:

INSERT INTO #tempTable
SELECT  theValuePreviouslyFetchedFromFunction
        ,ProductID
        ,VendorID
FROM    yourTable
WHERE   clientIDValue = @ClientID 
    AND dateValue <= @fromDate
    AND dateValue > @toDate

您可以在productID和vendorID上使用主键定义临时表。

然后,您可以将此表与这两列上的初始表连接,并将结果放在select。

如果没有更多示例代码,很难帮助您将所有函数分组到一个查询。

希望这有帮助。