存储过程与直接查询之间的不同输出

时间:2018-03-15 15:32:46

标签: sql-server tsql stored-procedures

我的存储过程在准备将数据发送到其他服务时使用了大约8个月。两天前它开始截断结果,但在那个时间段内代码没有任何变化。

这是一个奇怪的部分,如果我从存储过程中取出语句并且除了使其成为直接查询之外不做任何改变,我会得到预期的结果。

存储过程:5481行 直接查询:7490行

我已经尝试删除执行缓存,弹出服务器和服务,但这并没有解决它。我还设置了一个临时表来捕获存储过程中的任何准备好的批次,以便与直接查询进行比较,并且所有批次都匹配。

我不知道如何做到这一点。

编辑: 此处添加的代码

CREATE PROCEDURE [ETL].[spDeliverTransactionalFile]
    @TransactionDate DATE
    ,@MonthNum INT
AS
BEGIN

    SET NOCOUNT ON;

DECLARE @FiscalPeriodShort VARCHAR(10)
    ,@FiscalQuarterShort VARCHAR(9)
    ,@CalendarMonth INT


CREATE TABLE #MonthNum (
    FiscalPeriodShort VARCHAR(10)
    ,MaxDate DATE
    ,MonthNum INT
    )

IF @TransactionDate IS NULL OR @TransactionDate = '2006-12-31'
BEGIN
    INSERT INTO #MonthNum
    SELECT FiscalPeriodShort
       ,MAX(DateID) AS MaxDate
       ,ROW_NUMBER() OVER (ORDER BY MAX(DateID) ASC) AS MonthNum
    FROM dimDate
    WHERE FiscalQuarterShort = (
       SELECT FiscalQuarterShort
       FROM dimDate
       WHERE DateID = dbo.TransactionDateID(NULL)
       )
    GROUP BY FiscalPeriodShort
END
ELSE
BEGIN
    INSERT INTO #MonthNum
    SELECT FiscalPeriodShort
       ,MAX(DateID) AS MaxDate
       ,ROW_NUMBER() OVER (ORDER BY MAX(DateID) ASC) AS MonthNum
    FROM dimDate
    WHERE FiscalQuarterShort = (
       SELECT FiscalQuarterShort
       FROM dimDate
       WHERE DateID = @TransactionDate
       )
    GROUP BY FiscalPeriodShort

END


SELECT @FiscalPeriodShort = FiscalPeriodShort
FROM #MonthNum
WHERE MonthNum = @MonthNum

SELECT @CalendarMonth = MIN(CalendarMonth)
FROM dimDate
WHERE FiscalPeriodShort = @FiscalPeriodShort



SELECT CONVERT(VARCHAR(20),l.OrderId) AS OrderCode
    ,CONVERT(VARCHAR(10),ROW_NUMBER() OVER (PARTITION BY l.OrderID ORDER BY dp.Model, dr.RebateID)) + '-' + CONVERT(VARCHAR(10),l.factBookingLineSID) AS ItemCode
    ,'Sell' + @FiscalPeriodShort + '_' + CONVERT(VARCHAR(2),@CalendarMonth) AS BatchName
    ,'Sell' AS BatchType
    ,REPLACE(REPLACE(dp.Model, ', ', '-'), ',', '-') AS ProductName
    ,REPLACE(REPLACE(dst.SalesTeamName, ', ', '-'), ',', '-') AS GeographyName
    ,REPLACE(REPLACE(dc.CustomerName, ', ', '-'), ',', '-') AS CustomerName
    ,SUM(l.CurrentUnitQuantity) AS Quantity
    ,SUM(l.CurrentLineTotal) AS Amount
    ,'USD' AS AmountUnitType
    ,CONVERT(VARCHAR(10),dd.DateID,101) AS IncentiveDate
    ,'Sell' AS OrderType
    ,dst.SalesTeamID
    ,CASE WHEN dp.ProductGroupCode NOT IN ('Prod1','Prod2','Prod3','Prod4') THEN 'Group1'
        WHEN dp.ProductGroupCode = 'Prod3' AND l.FranchiseSID IN (1,3) THEN 'Group1'
        WHEN dp.ProductGroupCode = 'Prod4' AND l.FranchiseSID IN (1,3) THEN 'Group1'
        WHEN dp.ProductGroupCode IN ('Prod1','Prod2') THEN 'Group2'
        WHEN dp.ProductGroupCode = 'Prod3' AND l.FranchiseSID = 2 THEN 'Group2'
        WHEN dp.ProductGroupCode = 'Prod4' AND l.FranchiseSID = 2 THEN 'Group2'
        ELSE 'UKWN'
        END AS Product_Type
FROM factTransactionLine l
    INNER JOIN dimDate dd ON l.TransactionDateSID = dd.DateSID
    INNER JOIN dimProduct dp ON l.ProductLotSID = dp.ProductLotSID
    INNER JOIN dimSalesTeam dst ON l.CurrentSalesTeamSID = dst.SalesTeamSID
    INNER JOIN dimCustomer dc ON l.CustomerSID = dc.CustomerSID
WHERE l.Deleted = 0 
    AND dd.FiscalPeriodShort = @FiscalPeriodShort
GROUP BY l.OrderId
    ,dp.PartNumber
    ,dp.Model
    ,dc.CustomerName
    ,dd.DateID
    ,dst.SalesTeamName
    ,dst.SalesTeamID
    ,dp.ProductGroupCode
    ,l.FranchiseSID
    ,l.factTransactionLineSID
ORDER BY OrderCode
    ,ItemCode




DROP TABLE #MonthNum
END

在哪一点我使用以下语法运行存储过程:

EXEC etl.spDeliverTransactionalFile @TransactionDate = '2018-03-14', @MonthNum = 1

返回5481行。

但如果我从存储过程中取出查询如下:

DECLARE @TransactionDate DATE
    ,@MonthNum INT

SELECT @TransactionDate = '2018-03-14'
    ,@MonthNum = 1

DECLARE @FiscalPeriodShort VARCHAR(10)
    ,@FiscalQuarterShort VARCHAR(9)
    ,@CalendarMonth INT


CREATE TABLE #MonthNum (
    FiscalPeriodShort VARCHAR(10)
    ,MaxDate DATE
    ,MonthNum INT
    )

IF @TransactionDate IS NULL OR @TransactionDate = '2006-12-31'
BEGIN
    INSERT INTO #MonthNum
    SELECT FiscalPeriodShort
       ,MAX(DateID) AS MaxDate
       ,ROW_NUMBER() OVER (ORDER BY MAX(DateID) ASC) AS MonthNum
    FROM dimDate
    WHERE FiscalQuarterShort = (
       SELECT FiscalQuarterShort
       FROM dimDate
       WHERE DateID = dbo.TransactionDateID(NULL)
       )
    GROUP BY FiscalPeriodShort
END
ELSE
BEGIN
    INSERT INTO #MonthNum
    SELECT FiscalPeriodShort
       ,MAX(DateID) AS MaxDate
       ,ROW_NUMBER() OVER (ORDER BY MAX(DateID) ASC) AS MonthNum
    FROM dimDate
    WHERE FiscalQuarterShort = (
       SELECT FiscalQuarterShort
       FROM dimDate
       WHERE DateID = @TransactionDate
       )
    GROUP BY FiscalPeriodShort

END


SELECT @FiscalPeriodShort = FiscalPeriodShort
FROM #MonthNum
WHERE MonthNum = @MonthNum

SELECT @CalendarMonth = MIN(CalendarMonth)
FROM dimDate
WHERE FiscalPeriodShort = @FiscalPeriodShort



SELECT CONVERT(VARCHAR(20),l.OrderId) AS OrderCode
    ,CONVERT(VARCHAR(10),ROW_NUMBER() OVER (PARTITION BY l.OrderID ORDER BY dp.Model, dr.RebateID)) + '-' + CONVERT(VARCHAR(10),l.factBookingLineSID) AS ItemCode
    ,'Sell' + @FiscalPeriodShort + '_' + CONVERT(VARCHAR(2),@CalendarMonth) AS BatchName
    ,'Sell' AS BatchType
    ,REPLACE(REPLACE(dp.Model, ', ', '-'), ',', '-') AS ProductName
    ,REPLACE(REPLACE(dst.SalesTeamName, ', ', '-'), ',', '-') AS GeographyName
    ,REPLACE(REPLACE(dc.CustomerName, ', ', '-'), ',', '-') AS CustomerName
    ,SUM(l.CurrentUnitQuantity) AS Quantity
    ,SUM(l.CurrentLineTotal) AS Amount
    ,'USD' AS AmountUnitType
    ,CONVERT(VARCHAR(10),dd.DateID,101) AS IncentiveDate
    ,'Sell' AS OrderType
    ,dst.SalesTeamID
    ,CASE WHEN dp.ProductGroupCode NOT IN ('Prod1','Prod2','Prod3','Prod4') THEN 'Group1'
        WHEN dp.ProductGroupCode = 'Prod3' AND l.FranchiseSID IN (1,3) THEN 'Group1'
        WHEN dp.ProductGroupCode = 'Prod4' AND l.FranchiseSID IN (1,3) THEN 'Group1'
        WHEN dp.ProductGroupCode IN ('Prod1','Prod2') THEN 'Group2'
        WHEN dp.ProductGroupCode = 'Prod3' AND l.FranchiseSID = 2 THEN 'Group2'
        WHEN dp.ProductGroupCode = 'Prod4' AND l.FranchiseSID = 2 THEN 'Group2'
        ELSE 'UKWN'
        END AS Product_Type
FROM factTransactionLine l
    INNER JOIN dimDate dd ON l.TransactionDateSID = dd.DateSID
    INNER JOIN dimProduct dp ON l.ProductLotSID = dp.ProductLotSID
    INNER JOIN dimSalesTeam dst ON l.CurrentSalesTeamSID = dst.SalesTeamSID
    INNER JOIN dimCustomer dc ON l.CustomerSID = dc.CustomerSID
WHERE l.Deleted = 0 
    AND dd.FiscalPeriodShort = @FiscalPeriodShort
GROUP BY l.OrderId
    ,dp.PartNumber
    ,dp.Model
    ,dc.CustomerName
    ,dd.DateID
    ,dst.SalesTeamName
    ,dst.SalesTeamID
    ,dp.ProductGroupCode
    ,l.FranchiseSID
    ,l.factTransactionLineSID
ORDER BY OrderCode
    ,ItemCode




DROP TABLE #MonthNum

我将在7490行获得正确的数据。

2 个答案:

答案 0 :(得分:0)

这个

SELECT FiscalQuarterShort
FROM dimDate
WHERE DateID = dbo.TransactionDateID(NULL)

是非确定性的

为什么不重新分配@TransactionDate而不是重复所有代码?

答案 1 :(得分:0)

所以事实证明这是一个完全合格的问题。

在某些时候,在dimProduct的另一个模式下添加了另一个表。当按原样运行查询时,它默认为dbo。在存储过程下运行它时,它在用于ETL的备用模式下运行它。

我一直认为如果没有定义架构,查询引擎将默认为dbo,但这不是这种情况。