我有一个存储过程的代码。它在大约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
谢谢
答案 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
这就是我目前可以看到的所有问题,希望这会有所帮助。