SQL存储过程 - 修改代码

时间:2015-03-31 15:14:05

标签: sql-server tsql stored-procedures

我有一个存储过程的代码。它在大约4分钟内执行,这很好,但我的问题是,在创建它的方式中它只是删除并重新创建表,但我希望它删除一系列记录,再次从源处理它们并在表中插入更新值。

代码是:

ALTER PROCEDURE [BW].[InventoryBalance_EndingBalance]
AS
BEGIN
    SET NOCOUNT ON;

    --DROP TABLE DataWhs.dbo.InventoryBalancesEnd   
    DELETE DataWhs.dbo.InventoryBalancesEnd
    WHERE Period > (YEAR(GETDATE())-1)*100 + MONTH(GETDATE())+8


    SELECT DISTINCT 
        C.Period, ib.Account, ib.SalesOrg, IB.ProfitCenter, 
        IB.ValueType, IB.Plant, ib.SubscriptionKey
    INTO #Tempib6
    FROM 
        DataWhs.dbo.InventoryBalances ib
    CROSS JOIN
        DataWhs.Dates.Cumulated c
    WHERE 
        c.Period <= YEAR(GETDATE())*100 + MONTH(GETDATE())

    ALTER TABLE #Tempib6
    ADD [Amount_LC_EndBal] [numeric](18, 2), 
        [Amount_GC_EndBal] [numeric](18, 2);

    UPDATE T1 
    SET T1.Amount_LC_EndBal = (SELECT SUM(T2.Amount_LC)
                                FROM DataWhs.dbo.InventoryBalances T2 
                                WHERE T2.Period <= T1.Period 
                                  AND T1.Period NOT LIKE '%00' 
                                  AND T2.Period NOT LIKE '%00'
                                  AND T1.Account = T2.Account
                                  AND T1.ProfitCenter = T2.ProfitCenter
                                  AND T1.SalesOrg = T2.SalesOrg
                                  AND T1.ValueType = T2.ValueType
                                  AND T1.Plant = T2.Plant),
        T1.Amount_GC_EndBal = (SELECT SUM(T2.Amount_GC) 
                               FROM DataWhs.dbo.InventoryBalances T2 
                               WHERE T2.Period <= T1.Period 
                                 AND T1.Period NOT LIKE '%00' 
                                 AND T2.Period NOT LIKE '%00'
                                 AND T1.Account = T2.Account
                                 AND T1.ProfitCenter = T2.ProfitCenter
                                 AND T1.SalesOrg = T2.SalesOrg
                                 AND T1.ValueType = T2.ValueType
                                 AND T1.Plant = T2.Plant)
    FROM #Tempib6 T1;

    SELECT * 
    INTO dbo.InventoryBalancesEnd 
    FROM #Tempib6
    WHERE 
         #Tempib6.Amount_LC_EndBal IS NOT NULL 
         AND #Tempib6.Amount_LC_EndBal <> 0
         --(to remove comment after first full load) and #Tempib6.Period > 
         --(YEAR(GETDATE())-1)*100 + MONTH(GETDATE())+8

    DROP TABLE #Tempib6
END

谢谢

1 个答案:

答案 0 :(得分:1)

1赞不起评论。我猜测当前代码删除所有内容的原因是截断表格要比部分删除更有效。

据说上面有一些东西从你的删除逻辑中突然出现;

DELETE DataWhs.dbo.InventoryBalancesEnd
WHERE Period > (YEAR(GETDATE())-1)*100 + MONTH(GETDATE())+8

所以你删除了比4个月前更新的东西,至少我认为这是意图(1年+8个月)。然而,这不是一个数学上合理的方法,如果当前月份可能或更晚,您将最终得到像1413这样的值,这将是无效的年月组合。试试以下内容:

Declare @dateDelete datetime = (Select dateadd(month, -4, getdate()))
Declare @intFirstPeriod int = (select (YEAR(@dateDelete))*100 + MONTH(@dateDelete))
declare @intCurrentPeriod int = (select (YEAR(Getdate()))*100 + MONTH(@GetDate))
DELETE DataWhs.dbo.InventoryBalancesEnd
WHERE Period > @intFirstPeriod 

还需要更改另一部分以避免重复,首先选择查询,获取小于或等于当前期间的任何内容,这可能会复制超过4个月的任何内容。你在where子句中使用函数强制进行表扫描,你可以通过预先计算上述变量中​​的值来避免这种情况。在第一个选择使用相同的变量:

SELECT DISTINCT 
  C.Period, ib.Account, ib.SalesOrg, IB.ProfitCenter, IB.ValueType, IB.Plant, ib.SubscriptionKey
INTO #Tempib6
FROM 
  DataWhs.dbo.InventoryBalances ib
CROSS JOIN
  DataWhs.Dates.Cumulated c
WHERE c.Period between @intFirstPeriod and @intCurrentPeriod

这就是我目前可以看到的所有问题,希望这会有所帮助。