TSQL 使用同时更新的列 A 的值更新列 B

man*_*ysj 5 t-sql

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

下面是一个测试用例:

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
Run Code Online (Sandbox Code Playgroud)

上面的结果是:

ColA    ColB
8       0
Run Code Online (Sandbox Code Playgroud)

期望的结果是

ColA    ColB
8       -7
Run Code Online (Sandbox Code Playgroud)

更新语句在更新 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
Run Code Online (Sandbox Code Playgroud)

上述任一操作都会产生以下输出:

ColA    ColB
8       -7
Run Code Online (Sandbox Code Playgroud)

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

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

提前致谢!

Stu*_*Stu 2

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

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

select * from @TempIds;
Run Code Online (Sandbox Code Playgroud)