查找字符串中的每个字符并替换为另一个字符串中的字符

问题描述 投票:0回答:1

我有一个表,其中有两个名为 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 t-sql substring query-optimization
1个回答
0
投票

如果使用 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
???-123201-000000-000-???
104-234561-644221-123-947
104-123201-000000-000-947
111-222222-333333-444-555
xxx-xxxxxx-xxxxxx-xxx-xxx
?????????????????????????
123-654321-123456-456-789
123-654321-123456-456-789

null值表示没有计算出

NewCL
值,因为原始值不包含“?”。

© www.soinside.com 2019 - 2024. All rights reserved.