Как использовать табличные функции в SQL Server - PullRequest
1 голос
/ 17 мая 2011

У меня есть хранимая процедура здесь

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 Ответ

4 голосов
/ 17 мая 2011

Ответ на комментарий выше.

Что ж, вы должны сделать временную таблицу настолько большой, чтобы у вас были все записи (строки), которые не являются константами. И ограничить таблицу константами, т.е. @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.

Затем вы можете объединить эту таблицу с исходной в этих двух столбцах и получить результат в выборке.

Без какого-либо примера кода трудно помочь сгруппировать все функции в один запрос.

Надеюсь, это поможет.

...