我有一个表,其中有两个名为 IL 和 CL 的字符串类型列。我必须逐个字符地比较这两个字符串,无论 CL 列字符串中有问号,我都必须将其替换为另一列 (IL) 中完全相同位置的字符。
例如,与IL比较并替换问号后的CL字符串就是如下所示的New CL
CL | IL | 新CL |
---|---|---|
???-123201-000000-000-??? | 104-234561-644221-123-947 | 104-123201-000000-000-947 |
我有下面的代码工作,其中
while
内部有一个 cursor
循环,遍历字符串的每个字符,连接成一个新字符串,然后在最后用新值进行更新。然而,这段代码的性能非常慢,因为表有 100K+ 条记录,并且每行循环 25 次(字符串长度)。我想看看是否有办法重写这个逻辑集以提高性能。
declare CharC insensitive cursor for
select ID, IL, CL
from AcctStrings
where CL like '%?%'
open CharC
fetch next from CharC into @ID, @IL, @CL
while @@fetch_status = 0 begin
set @NewCL = ''
set @i = 1
while @i <= 25 begin
set @TestChar = substring(@CL,@i,1)
set @OtherChar = substring(@IL,@i,1)
if (@TestChar = '?') begin
set @NewCL = @NewCL + @OtherChar
end
else
set @NewCL = @NewCL + @TestChar
set @i = @i + 1
end
update AcctStrings
set CL = @NewCL
where ID = @ID
end
fetch next from CharC into @ID, @IL, @CL
end
deallocate CharC
如果使用 SQL Server 2022,您可以尝试以下操作:
UPDATE AcctStrings
SET CL = (
SELECT STRING_AGG(N.NewC, '') WITHIN GROUP(ORDER BY S.Value)
FROM GENERATE_SERIES(1, LEN(CL)) S
CROSS APPLY(SELECT SUBSTRING(CL, S.value, 1) AS C) O
CROSS APPLY(SELECT CASE WHEN O.C = '?' THEN SUBSTRING(IL, S.value, 1) ELSE O.C END AS NewC) N
)
WHERE CL LIKE '%?%'
上面使用子查询将
CL
字符串分解为单个字符,应用转换(需要时),然后重建更新的字符串。
请参阅 this db<>fiddle 进行演示。
结果(带有一些额外的测试数据):
CL | IL | 新CL |
---|---|---|
|
|
|
|
|
空 |
|
|
|
null值表示没有计算出
NewCL
值,因为原始值不包含“?”。