sql-server - T-SQL如何仅在其他值实际更改时设置没有触发器的修改日期

标签 sql-server tsql

我的总体目标是仅更新需要更新的“部分”上的 [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')

最佳答案

通过 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] 字段的值可能没有差异。

关于sql-server - T-SQL如何仅在其他值实际更改时设置没有触发器的修改日期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27362612/

相关文章:

mysql - 复杂条件连接

php - 从 php 调用 MSSQL 存储过程

sql-server - View 中具有静态值的另一个表中的 SQL Server 列

SQL Server - 如何向上或向下舍入小数?

sql-server - SQL Server 错误 [SQLState 42000](错误 325)

sql-server - 从存储过程插入不同的列

sql - 如何优化 SQL 查询?

sql - 合并另一个表中的数据时违反主键

sql - 显示日期大于当前日期

sql - 如何制作这个sql语句