用SQL中的不同替换列多次替换同一字符

时间:2019-11-23 22:12:55

标签: sql sql-server replace

我一直在摸索如何使用SQL Server REPLACESTUFFSUBSTRINGCONCAT来实现此目的,例如。没有最终解决方案怎么办。

我有一个字符串示例:

'Product # has not been created for company # with language #'

我需要做的是更改每个'#',使不同列的结果不同:

  • '#'列中的第一个Data1应该替换为内容'P0001'
  • '#'列中Data2中第二个'1000',内容为'#'
  • Data3中的第三'EN',内容为'Product P0001 has not been created for company 1000 with language EN'

因此最终结果应如下所示:

{{1}}

2 个答案:

答案 0 :(得分:2)

一种选择是在#上分割字符串,然后简单地重建它

示例

Declare @S varchar(max) = 'Product # has not been created for company # with language #'

Select concat(
              xDim.value('/x[1]','varchar(max)')
             ,'P0001'
             ,xDim.value('/x[2]','varchar(max)')
             ,'1000'
             ,xDim.value('/x[3]','varchar(max)')
             ,'EN'
             ,xDim.value('/x[4]','varchar(max)')  
             )
 From ( values ( cast('<x>'+ replace( (Select replace(@S,'#','§§Split§§') as [*] For XML Path('')),'§§Split§§', '</x><x>') + '</x>' as xml ))) as A(xDim)

返回

NewValue
Product P0001 has not been created for company 1000 with language EN

答案 1 :(得分:1)

使用recursive CTE

create table tablename(data varchar(max), data1 varchar(100), data2 varchar(100), data3 varchar(100));
insert into tablename(data, data1, data2, data3) values
('Product # has not been created for company # with language #', 'P0001', '1000', 'EN'),
('First # second # third # end', '1st', '2nd', '3d'),
('# a # b # c', '1', '2', '3');

with 
  cte as (
    select 2 id, data1, data2, data3, 
      case 
        when charindex('#', data) = 0 then data
        else left(data, charindex('#', data) - 1) +
             data1 +
             substring(data, charindex('#', data) + 1, len(data))
      end data  
    from tablename
    union all
    select id + 1, data1, data2, data3, 
      case 
        when charindex('#', data) = 0 then data
        else left(data, charindex('#', data) - 1) + 
             choose(id, data1, data2, data3) +              
             substring(data, charindex('#', data) + 1, len(data)) 
      end
    from cte
    where charindex('#', data) > 0
  )
select data 
from cte 
where charindex('#', data) = 0

请参见demo
结果:

> | data                                                                 |
> | :------------------------------------------------------------------- |
> | 1 a 2 b 3 c                                                          |
> | First 1st second 2nd third 3d end                                    |
> | Product P0001 has not been created for company 1000 with language EN |