这是适合使用游标的(非常)罕见的情况之一。事实上,这相当复杂——一个可更新的游标以及动态 SQL。
这是想法:
declare @col1 int;
declare @col2 int;
declare @col3 nvarchar(max);
declare @sql nvarchar(max);
declare @col4 int;
DECLARE c CURSOR
FOR SELECT col1, col2, col3 FROM t FOR UPDATE;
OPEN c;
FETCH NEXT FROM c INTO @col1, @col2, @col3;
WHILE @@fetch_status = 0
BEGIN
set @sql = 'select @col4=[col3] from (select @col1 as col1, @col2 as col2) t';
set @sql = replace(@sql, '[col3]', @col3);
exec sp_executesql @sql, N'@col1 int, @col2 int, @col4 int output',
@col1=@col1, @col2=@col2, @col4=@col4 output;
SELECT @col1, @col2, @col3, @col4;
UPDATE t
set col4 = @col4
WHERE current of c;
FETCH NEXT FROM c INTO @col1, @col2, @col3;
END;
CLOSE c;
DEALLOCATE c;
这是一个 db<>fiddle 。
请注意,这不会很快。在这样的查询上获得性能是相当困难的,但是您可以将表分成块并使用单独的线程更新每个块。