根据相同 table 中的值解析和替换列中的嵌套模式

Parse and replace nested pattern in column based on values in the same table

我遇到以下问题: 我需要用替换字符串替换某些字符串模式。使用 Replace 这本身很容易,但我遇到的问题是字符串模式可以相互嵌套 示例:

Select 'p1' as param, 'P1-Value' as paramvalue into #paramvalues
Union 
Select 'p2' as param, 'P2-Value' as paramvalue
Union
Select 'p3' as param, 'P3-Value except $p1$' as paramvalue
Union
Select 'p4' as param, 'P4-Value, $p1$,$p2$, $p3$' as paramvalue

Table::

 param   paramvalue
 p1      P1-Value
 p2      P2-Value
 p3      P3-Value execpt $p1$
 p4      P4 Value, $p1$,$p2$,$p3$

现在我想用实际值替换字段 paramvalue 中的 $param$ 字符串模式。对于单个值,可以使用 replace:

来完成
Select param, REPLACE(paramvalue,'$p1$',(Select paramvalue from #paramvalues a where   param = 'p1'))
from #paramvalues b


 param   paramvalue
 p1      P1-Value
 p2      P2-Value
 p3      P3-Value execpt P1-Value
 p4      P4 Value, P1-Value,$p2$,$p3$

但它只会替换一层嵌套,而且不会考虑替换值。我想过使用嵌套 Replace 但我想保持动态,因此添加新参数不需要重新编码。嵌套级别也没有定义 bevorhand(但为了简单起见,我现在可以将其定义为三个)。 我想我需要在 CTE 中使用一些递归 SQL,但无法弄清楚如何让它工作。

最终结果集应如下所示:

 param   paramvalue
 p1      P1-Value
 p2      P2-Value
 p3      P3-Value execpt P1-Value
 p4      P4 Value, P1-Value,P2-Value,P3-Value execpt P1-Value

Sql 服务器:2008 R2

感谢任何帮助

您需要创建一个这样的函数,用它们的值替换参数。

这里还有一个SQL Fiddle demo

create function replace_params (@pvalue varchar(255))
returns varchar(255)
as
begin
declare @string_builder varchar(255) = ''
declare @temp_param varchar(255) = ''
declare @flag as int = 0
declare @i as int = 1
declare @chr char(1)

while (@i <= len(@pvalue))
begin
  set @chr = substring(@pvalue, @i, 1)
  if @flag = 1
  begin
    if @chr = '$'
    begin
      set @string_builder = @string_builder + (select top 1 dbo.replace_params(param_value) from params where param = @temp_param)
      set @temp_param = ''
      set @flag = 0
    end
    else
    begin
      set @temp_param = @temp_param + @chr
    end
  end
  else
  begin
    if @chr = '$' 
    begin
      set @flag = 1
    end
    else 
    begin
      set @string_builder = @string_builder + @chr
    end
  end
  set @i = @i + 1
end

   return(@string_builder)
end
go