使用掩码和规则更新SQL数据

使用掩码和规则更新SQL数据,sql,sql-server-2012,sql-update,mask,data-masking,Sql,Sql Server 2012,Sql Update,Mask,Data Masking,我在SQL 2012的一个专栏中有大约3000个条目,它们目前是非结构化的 1.1.01.10、1.1.1.11 我想将数据转换成一种格式,其中包括所有单个数字的前导0,即 01.01.01.10等等 有没有办法通过更新查询来实现这一点?我可以通过导出到excel并在其中进行操作来实现这一点,但如果可能的话,我希望避免这种情况。如果数据始终有4个块,则可以一次将它们分解为一个单元 Alter function Pad ( @str varchar(max) ) returns varc

我在SQL 2012的一个专栏中有大约3000个条目,它们目前是非结构化的

1.1.01.10、1.1.1.11

我想将数据转换成一种格式,其中包括所有单个数字的前导0,即

01.01.01.10等等


有没有办法通过更新查询来实现这一点?我可以通过导出到excel并在其中进行操作来实现这一点,但如果可能的话,我希望避免这种情况。

如果数据始终有4个块,则可以一次将它们分解为一个单元

Alter function Pad
(
    @str varchar(max) 
)
returns varchar(max)
as
begin
Declare @nstr varchar(max)

while(PATINDEX('%.%',@str)<>0)
  begin
    Set @nstr = isnull(@nstr,'')+case when PATINDEX('%.%',@str) = 2 then '0'+substring(@str,PATINDEX('%.%',@str)-1,1) else SUBSTRING(@str,1,PATINDEX('%.%',@str)-1) end+'.'
    Set @str = case when PATINDEX('%.%',@str) = 2 then stuff(@str,PATINDEX('%.%',@str)-1,2,'') else stuff(@str,1,PATINDEX('%.%',@str),'') end 
  end
Set @nstr = isnull(@nstr,'')+case when len(@str) <> 1 then @str when len(@str) = 1 then '0'+@str else '' end 
return @nstr
end



update t
set num = [dbo].pad(num)
from table t
With F AS (
  SELECT data
       , rem = substring(data, patindex('%.%', data) + 1, len(data))
       , value1 = substring(data, 1, patindex('%.%', data) - 1)
  FROM   Table1
), S AS (
  SELECT data
       , rem = substring(rem, patindex('%.%', rem) + 1, len(rem))
       , value1
       , value2 = substring(rem, 1, patindex('%.%', rem) - 1)
  FROM   F
), T AS (
  SELECT data
       , value1
       , value2
       , value3 = substring(rem, 1, patindex('%.%', rem) - 1)
       , value4 = substring(rem, patindex('%.%', rem) + 1, len(rem))
  FROM   S
)
UPDATE T SET  
       Data = CONCAT(RIGHT('00' + value1, 2), '.'
                   , RIGHT('00' + value2, 2), '.'
                   , RIGHT('00' + value3, 2), '.'
                   , RIGHT('00' + value4, 2));
查询可以缩小,但会失去可读性

如果块的数量未知和/或行与行之间可能发生变化,则查询会更复杂,并涉及递归CTE

CTE的锚查询获取值中的第一个块,用块数设置pos,并准备结果res。 runner查询适用于以下块,但不适用于最后一个块,搜索第n个块并向结果中添加块。
停止查询在不搜索另一个无法找到的点的情况下获取最后一个块,并完成结果的构造。最初将pos设置为块数后,现在将为1。

数据是否总是采用相同的格式,即可能的最大长度字符串是,比如11.11.11.11?您是否可以检查函数并在u r表中更新相同的值,并让我知道它是否在工作?不,字符串长度可以运行到三个整数之间。it’不幸的是,Yazar——现在就要尝试一下,让你知道,太棒了
With Splitter AS (
  -- anchor
  SELECT data
       , rem = substring(data, patindex('%.%', data) + 1, len(data))
       , pos = len(data) - len(replace(data, '.', '')) + 1
       , value = substring(data, 1, patindex('%.%', data) - 1)
       , res = CAST('' as nvarchar(50))
  FROM   Table1
  UNION ALL
  -- runner
  SELECT data
       , rem = substring(rem, patindex('%.%', rem) + 1, len(rem))
       , pos = pos - 1
       , value = substring(rem, 1, patindex('%.%', rem) - 1)
       , res = CAST(res + RIGHT('00' + value, 2) + '.' as nvarchar(50))
  FROM   Splitter
  WHERE  patindex('%.%', rem) > 1
  UNION ALL
  -- stop
  SELECT data
       , rem = ''
       , pos = pos - 1
       , value = rem
       , res = CAST(res + RIGHT('00' + value, 2) 
                  + '.' + RIGHT('00' + rem, 2) as nvarchar(50))
  FROM   Splitter
  WHERE  patindex('%.%', rem) = 0
    AND  rem <> ''
)
UPDATE table1 Set
  Data = res
FROM   table1 t
       INNER JOIN Splitter s ON t.Data = s.Data and s.Pos = 1