【问题标题】:Replace all characters of string to asterisks except first characters and space in MSSQL将字符串的所有字符替换为星号,除了 MSSQL 中的第一个字符和空格
【发布时间】:2014-04-07 05:51:11
【问题描述】:

我想知道是否可以通过函数在 mssql 中对敏感数据进行哈希处理,并为所有字段保留第一个字符“原样”。示例:

“Jon Kirk”的名字应该被提取为 J** K***

【问题讨论】:

    标签: sql-server sql-server-2008 tsql sql-server-2008-r2 sql-server-2012


    【解决方案1】:

    我最初发布了一个递归解决方案。这更快:

    declare @name varchar(20) = 'Jon Kirk'
    
    declare @loop int = len(@name)
    
    while @loop > 1
    select @name = stuff(@name, @loop, 1, 
    case when substring(@name, @loop-1,2) like '% ' then ' '
         when substring(@name, @loop-1,2) like ' %' then substring(@name, @loop,1)
    else '*' end), @loop+=-1
    
    select @name
    

    【讨论】:

    • 找到更快的解决方案。查看我的更新答案
    【解决方案2】:

    这样的事情怎么样?

    declare @s varchar(50) = 'Jon kirk'
    
    ;with cte as (
        select 1 as i, cast (' ' + ltrim (@s) as varchar(50)) as s
        union all
        select i + 1
            , cast (
                case when substring (s, i, 2) like '% %'
                then s
                else stuff (s, i + 1, 1, '*') end
            as varchar(50))
        from cte
        where i < len (s)
    )
    
    select top 1 ltrim (s) as s
    from cte
    order by i desc
    

    这是最快的解决方案(虽然它一点也不漂亮):

    declare @s varchar(50) = 'Jon kirk'
    
    select left (
          left (@s, 1)
        + case when substring (@s, 1, 2) like '% %' then substring (@s, 2, 1) else '*' end
        + case when substring (@s, 2, 2) like '% %' then substring (@s, 3, 1) else '*' end
        + ...
        + case when substring (@s, 48, 2) like '% %' then substring (@s, 49, 1) else '*' end
        + case when substring (@s, 49, 2) like '% %' then substring (@s, 50, 1) else '*' end
        , len (@s) )
    

    【讨论】:

    • 第一个字母是小写怎么办。
    • 我一开始尝试使用递归,使用简单的while循环更有效。在从修改列表中选择结果之前,您将所有结果存储在内存中。
    • 是的。您的非递归解决方案出现得更快。
    【解决方案3】:

    如果你的名字被分开并且中间不包含空格,你可以更快地隐藏敏感信息而不会做奇怪的循环:

    DECLARE @t as varchar(20) = 'Billy'
    
    SELECT CONCAT( LEFT(@t, 1), REPLICATE('*', LEN(@t) - 1) )
    

    输出B****

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-23
      • 1970-01-01
      相关资源
      最近更新 更多