【问题标题】:How to use table valued functions in SQL Server如何在 SQL Server 中使用表值函数
【发布时间】:2011-08-27 00:06:12
【问题描述】:

我这里有一个存储过程

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

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

【问题讨论】:

  • 您是否也打算在其他SP中使用该功能?否则我会使用临时表或声明的表来获得使用主键的能力。如果数据很多,表值函数连接会很慢。
  • @Johan 我如何使用临时表做到这一点?

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


【解决方案1】:

回答上面的评论。

嗯,你应该把临时表做得很大,这样你就有了所有不是常量的条目(行)。并使用常量限制表格,即@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 上的主键定义临时表。

然后您可以将这个表与这两列上的初始表连接起来,并将结果放在选择中。

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

希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 2010-10-31
    • 1970-01-01
    • 2017-03-14
    • 2013-02-11
    • 2021-07-28
    • 1970-01-01
    • 2021-09-09
    • 2010-12-07
    • 2016-02-29
    相关资源
    最近更新 更多