【问题标题】:TSQL Update Column B with Column A's Value that is also being updatedTSQL 使用列 A 的值更新列 B 也正在更新
【发布时间】:2022-01-14 08:19:15
【问题描述】:

我正在处理表中的 155+ 百万行并分批执行以提高性能,但遇到了列中的值未按预期更新的情况。我知道我可以通过几种不同的方式来解决它,但我想看看是否有人知道如何在单个更新语句中做到这一点。

下面是一个测试用例:

DECLARE @TempIds TABLE (    
    ColA int,
    ColB int
) 

--seed the values for a test
INSERT INTO @TempIds (ColA,ColB) VALUES (1, 2)

--do the update
UPDATE @TempIds SET ColA = (3+5), ColB = (1-ColA) 

--see the results
SELECT * FROM @TempIds

上面的结果是:

ColA    ColB
8       0

期望的结果是

ColA    ColB
8       -7

更新语句在更新 ColB 时使用 ColA 的当前值为“1”,而不是使用 ColA 的最终值为“8”。

我知道我可以通过执行以下操作之一来解决此问题:

UPDATE @TempIds SET ColA = (3+5)
UPDATE @TempIds SET ColB = (1-ColA) 
    
--see the results
SELECT * FROM @TempIds
    
OR 
    
UPDATE @TempIds SET ColA = (3+5), ColB = 1-(3+5)
    
--see the results
SELECT * FROM @TempIds

以上任何一种都将导致以下输出:

ColA    ColB
8       -7

这是一个简化版本,因为实际查询有很多计算和公式来计算 ColA 的值。

我试图避免两个更新语句或需要在 ColB 公式中重复 ColA 的公式。

提前致谢!

【问题讨论】:

  • 我知道这可能是一个非常简单的例子。但是将ColB 设为计算列会解决您的问题吗?
  • @Squirrel 在这种情况下,将其设置为计算列会导致性能问题,因为 ColB 也用于其他查询作为 where 子句的一部分。我的理解是这会导致性能问题,尤其是在查询大型表时。
  • 计算列可以被持久化和索引,因此它可能不会达到您期望的性能。

标签: tsql


【解决方案1】:

您是否可以通过首先创建一个新列 A 然后引用它来使用可更新 CTE:

with updateme as (
    select *, (3+5) as NewA
    from @TempIds
)
update updateme set colA = NewA, colb = 1-NewA;

select * from @TempIds;

【讨论】:

  • 这肯定行得通,我已经多次使用 CTE。我的情况的复杂性至少需要 2 个 CTE,因为我的 ColA 和 ColB 示例实际上是 ColA、ColB、ColC、ColD 和几个以特定顺序相互依赖的。 @sticky-bit 下面提到的解决方案也有效。我从来没有在更新语句中设置列值的同时使用变量,但它确实有效。我创建了 2 个变量,并且能够正确更新所有 4 列。非常感谢您的建议,因为它在不同的情况下很有帮助。
【解决方案2】:

可以使用变量。

DECLARE @newcola integer;
UPDATE @tempids
       SET @newcola = cola = 3 + 5,
           colb = 1 - @newcola;

db<>fiddle

【讨论】:

  • 我从来没有在更新语句中设置列值的同时使用变量,但它确实有效。我创建了 2 个变量,并且能够正确更新所有 4 列,并且每个变量都正确级联。谢谢你为我节省了大量时间。
  • @manrysj From update: "SET @variable = column = expression 将变量设置为与列相同的值。这与 SET @variable 不同= column, column = expression,将变量设置为列的更新前值。"
猜你喜欢
  • 2012-11-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-12
  • 2021-12-10
相关资源
最近更新 更多