简体   繁体   English

sql server,用表中的值替换字符串中的字符

[英]sql server, replace chars in string with values in table

how can i replace values in string with values that are in a table?如何用表中的值替换字符串中的值?

for example例如

    select *
into #t
from 
(
    select 'bla'c1,'' c2 union all
    select 'table'c1,'TABLE' c2 union all
    select 'value'c1,'000' c2 union all
    select '...'c1,'' c2
)t1

declare @s nvarchaR(max)='this my string and i want to replace all values that are in table #t'

i have some values in my table and i want to replace C1 with C2 in my string.我的表中有一些值,我想在我的字符串中用 C2 替换 C1。

the results should be结果应该是

this my string and i want to replace all 000 that are in TABLE #t这是我的字符串,我想替换 TABLE #t 中的所有 000

UPDATE: i solved with a CLR更新:我用 CLR 解决了

using System;
using Microsoft.SqlServer.Server;
using System.Data.SqlTypes;
using System.Data.Linq;

namespace ReplaceValues
{
    public partial class Functions
    {
        [SqlFunction
            (
                //DataAccess = DataAccessKind.Read,
                SystemDataAccess = SystemDataAccessKind.Read
            )
        ]
        public static string ReplaceValues(string row, string delimitator, string values, string replace/*, bool CaseSensitive*/)
        {
            //return row;
            string[] tmp_values = values.Split(new string[] { delimitator }, StringSplitOptions.None);
            string[] tmp_replace = replace.Split(new string[] { delimitator }, StringSplitOptions.None);

            row = row.ToUpper();

            for (int i = 0; i < Math.Min(tmp_values.Length, tmp_replace.Length); i++)
            {
                row = row.Replace(tmp_values[i].ToUpper(), tmp_replace[i]);
            }

            return row;
        }

    }
}

and then接着

select *
into #t
from 
(
    select 'value1'OldValue,'one'NewValue union all
    select 'value2'OldValue,'two'NewValue union all
    select 'value3'OldValue,'three'NewValue union all
    select 'value4'OldValue,'four'NewValue
)t1


select dbo.ReplaceValues(t1.column,'|',t2.v,t2.r)
from MyTable t1
cross apply
(
    select dbo.inlineaggr(i1.OldValue,'|',1,1)v,
           dbo.inlineaggr(i1.NewValue,'|',1,1)r
    from #t i1
)t2

i have to improved it to manage better the case sensitive, but performance are not bad.我必须改进它以更好地管理区分大小写,但性能还不错。 (also 'inlineaggr' is a CLR i wrote years ago) ('inlineaggr' 也是我多年前写的一个 CLR)

You can do this via recursion.您可以通过递归来做到这一点。 Assuming you have a table of find-replace pairs, you can number the rows and then use recursive cte:假设您有一个查找-替换对表,您可以对行进行编号,然后使用递归 cte:

create table #t(c1 nvarchar(100), c2 nvarchar(100));
insert into #t(c1, c2) values
('bla', ''),
('table', 'table'),
('value', '000'),
('...', '');

declare @s nvarchar(max) = 'this my string and i want to replace all values that are in table #t';

with ncte as (
    select row_number() over (order by (select null)) as rn, *
    from #t
), rcte as (
    select rn, replace(@s, c1, c2) as newstr
    from ncte
    where rn = 1

    union all

    select ncte.rn, replace(rcte.newstr, ncte.c1, ncte.c2)
    from ncte
    join rcte on ncte.rn = rcte.rn + 1
)
select *
from rcte
where rn = 4

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM