2015-03-31 55 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