我的总体目标是仅在"部件"上更新[StandardUnitCost]字段。需要更新,同时仅在相同的行上更新[DateUpdated]字段。我使用的工具只通过匹配[DateUpdated]列来同步数据,因此重要的是它只会在[StandardUnitCost]也更新的行上发生更改。重要的是两者都发生,并且只在同一行上发生。如果[StandardUnitCost]字段将使用与其当前具有的值相同的值进行更新,则该值未更改,并且[DateUpdated]字段应不更新。
我目前将此作为两个单独的更新语句,需要帮助将它们组合在一起。
Update [mas_wgd].[dbo].[CI_Item]
Set dateupdated = CASE
WHEN StandardUnitCost < AverageUnitCost then convert (date, GETDATE())
WHEN (AverageUnitCost + 2) >= 22.0
AND standardunitcost > (AverageUnitCost + 2.000000) then convert (date, GETDATE())
When StandardUnitCost < 22.000000
And StandardUnitCost > 0 then convert (date, GETDATE())
Else dateupdated
end
Where ProductLine IN ('A010', 'A020', 'A030', 'A040', 'A050', 'A060', 'A070', 'A080',
'A090', 'A100', 'A110', 'A120', 'A130', 'A130', 'A140', 'A150', 'A200', 'A250',
'A300', 'A350', 'A400', 'A450', 'A500', 'A550', 'A600', 'AGNC', 'C010', 'C020',
'C030', 'C040', 'C050', 'C060', 'C070', 'C080', 'C090', 'C100', 'C110', 'C120',
'C130', 'C130', 'C140', 'C150', 'C200', 'C250', 'C300', 'C350', 'C400', 'C450',
'C500', 'C550', 'C600', 'CGNC')
Update [mas_wgd].[dbo].[CI_Item]
Set Standardunitcost = CASE
WHEN (AverageUnitCost between 0.010000 and 22.000000) Then 22.00000
WHEN AverageUnitCost > 22.000000 then AverageUnitCost + 2.000000
Else StandardUnitCost
end
Where ProductLine IN ('A010', 'A020', 'A030', 'A040', 'A050', 'A060', 'A070', 'A080',
'A090', 'A100', 'A110', 'A120', 'A130', 'A130', 'A140', 'A150', 'A200', 'A250',
'A300', 'A350', 'A400', 'A450', 'A500', 'A550', 'A600', 'AGNC', 'C010', 'C020',
'C030', 'C040', 'C050', 'C060', 'C070', 'C080', 'C090', 'C100', 'C110', 'C120',
'C130', 'C130', 'C140', 'C150', 'C200', 'C250', 'C300', 'C350', 'C400', 'C450',
'C500', 'C550', 'C600', 'CGNC')
答案 0 :(得分:3)
通过CTE执行此操作将允许您指定一次公式并使用它来触发两个字段的更新:
SET NOCOUNT ON;
SET ANSI_NULLS ON;
DECLARE @Test TABLE (ID INT NOT NULL IDENTITY(1, 1),
AverageUnitCost INT NULL,
StandardUnitCost INT NULL,
ModifiedDate DATETIME,
WasUpdated BIT NULL);
INSERT INTO @Test VALUES (5, 8, GETDATE(), 0);
INSERT INTO @Test VALUES (15, 11, GETDATE(), 0);
INSERT INTO @Test VALUES (12, 35, GETDATE(), 0);
INSERT INTO @Test VALUES (22, 47, GETDATE(), 0);
SELECT * FROM @Test;
;WITH cte AS
(
SELECT tmp.ID,
tmp.StandardUnitCost,
tmp.ModifiedDate,
tmp.WasUpdated,
CASE WHEN tmp.AverageUnitCost BETWEEN 10 AND 20 THEN 22
WHEN tmp.AverageUnitCost > 20 THEN (tmp.AverageUnitCost + 2)
ELSE tmp.StandardUnitCost
END AS [NewValue]
FROM @Test tmp
--WHERE ProductLine IN ('A010'...) -- this is part of the real table so uncomment
)
UPDATE tab
SET tab.StandardUnitCost = tab.NewValue,
tab.ModifiedDate = GETDATE(),
tab.WasUpdated = 1 -- only here to clearly indicate that the row was updated
FROM cte tab
WHERE tab.StandardUnitCost <> tab.NewValue;
SELECT * FROM @Test;
[WasUpdated]字段仅在那里,因为语句运行得足够快,而且在更新的行上[ModifiedDate]字段的值可能没有差异。
答案 1 :(得分:2)
我相信您可以通过将StandardCost
更新的条件移到WHERE
子句来简化查询,在这种情况下,您将确保匹配的行将被更新,因此也可以放心地加时间戳dateupdated
列同时显示:
Update [mas_wgd].[dbo].[CI_Item]
Set dateupdated = convert (date, GETDATE()),
Standardunitcost =
CASE
WHEN (AverageUnitCost between 0.010000 and 22.000000) Then 22.00000
WHEN AverageUnitCost > 22.000000 then AverageUnitCost + 2.000000
END -- CASE
Where ProductLine IN ('A010', ... 'CGNC')
AND (AverageUnitCost > 0.010000);
CASE
上的StandardUnitCost
更新之间的共同主题似乎是AverageUnitCost
大于0.010000
时会更新。
这也可以避免对Set dateupdated = dateupdated
和Standardunitcost = Standardunitcost