2015-03-31 100 views
0

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

的代码是:

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 

感谢

+0

这不是一个问题,即使你称之为一个。 – Jodrell 2015-03-31 15:22:24

+0

哪个RDBMS是为了这个?请添加一个标签来指定您是使用'mysql','postgresql','sql-server','oracle'还是'db2' - 或者其他的东西。 – 2015-03-31 15:43:33

+0

你的问题到底是什么? – 2015-03-31 15:54:30

回答

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 

这是关于我目前可以看到的所有问题,希望对您有所帮助。

+0

非常感谢,Randall Mathews – Adriana 2015-03-31 17:40:10