Поиск пробелов из нешифрованной / неанглийской строки - PullRequest
0 голосов
/ 27 марта 2019

В моем коде мне нужно отобразить имя в каком-то указанном формате, в котором каждый символ должен быть заменен символом '*'.Тем не менее, мне не нужно заменять пробелы.

Теперь, так как это японское приложение, имена могут содержать японские пробелы.Может ли какой-нибудь помочь мне с общим способом выявления космических персонажей.То, что я сделал, в скрипке .

DECLARE @Name NVARCHAR(50) = N'ab cb';
select IIF(LEN(LTRIM(substring(a.Name, v.number, 1))) = 0, substring(a.Name, v.number, 1), '*')
from (select @Name Name) a
join (  SELECT (1 + ones.n + ISNULL(10*tens.n, 0) + ISNULL(100*thausand.n, 0))  Number
      FROM  (VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) ones(n),
            (VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) tens(n),
            (VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) thausand(n)
  )V on v.Number <= len(a.Name);

SET @Name = N'中山 大地';
select IIF(LEN(LTRIM(substring(a.Name, v.number, 1))) = 0, substring(a.Name, v.number, 1), '*')
from (select @Name Name) a
join (  SELECT (1 + ones.n + ISNULL(10*tens.n, 0) + ISNULL(100*thausand.n, 0))  Number
      FROM  (VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) ones(n),
            (VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) tens(n),
            (VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) thausand(n)
  )V on v.Number <= len(a.Name);

Ответы [ 2 ]

2 голосов
/ 27 марта 2019

Учитывая, что все символы со свойством пробела здесь , необходимый запрос может выглядеть так:

DECLARE @Name NVARCHAR(50) = N'ab cb';
select IIF(LEN(LTRIM(substring(a.Name, v.number, 1))) = 0, substring(a.Name, v.number, 1), '*')
from (select @Name Name) a
join (  SELECT (1 + ones.n + ISNULL(10*tens.n, 0) + ISNULL(100*thausand.n, 0))  Number
      FROM  (VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) ones(n),
            (VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) tens(n),
            (VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) thausand(n)
  )V on v.Number <= len(a.Name);

SET @Name = N'中山 大地';

with
  wss as (
    select nchar(u) ws
    from(values(0x0009), (0x000A), (0x000B), (0x000C), (0x000D),
               (0x0085), (0x2028), (0x2029), (0x0020), (0x3000),
               (0x1680), (0x2000), (0x2001), (0x2002), (0x2003),
               (0x2004), (0x2005), (0x2006), (0x2008), (0x2009),
               (0x200A), (0x205F), (0x00A0), (0x2007), (0x202F)) ws(u)
  )
select IIF(LEN(LTRIM(substring(a.Name, v.number, 1))) = 0, substring(a.Name, v.number, 1), '*') replace1,
  iif(substring(a.Name, v.number, 1) in (select ws from wss), substring(a.Name, v.number, 1), '*') replace2
from (select @Name Name) a
join (  SELECT (1 + ones.n + ISNULL(10*tens.n, 0) + ISNULL(100*thausand.n, 0))  Number
      FROM  (VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) ones(n),
            (VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) tens(n),
            (VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) thausand(n)
  )V on v.Number <= len(a.Name);

Вывод:

+------------------+
| (No column name) |
+------------------+
| *                |
| *                |
|                  |
| *                |
| *                |
+------------------+

+----------+----------+
| replace1 | replace2 |
+----------+----------+
| *        | *        |
| *        | *        |
| *        |          |
| *        | *        |
| *        | *        |
+----------+----------+

Протестируйте его онлайн с Rextester .

0 голосов
/ 27 марта 2019

Это легко сделать в SQL2017.

DECLARE @Name NVARCHAR(50) = N'中山 大地';

SELECT STRING_AGG(replicate('*', LEN(value)), ' ') AS obfuscated
FROM STRING_SPLIT(@name, ' ') 

obfuscated

STRING_SPLIT SQL2016

STRING_AGG SQL2017

Однако для более старых версий SQL Server это может быть немного сложнее.

String Split:

DECLARE @Name NVARCHAR(50) = N'ab cd e';

SELECT Split.a.value('.', 'NVARCHAR(MAX)') AS data_field
FROM   ( SELECT CAST('<X>' + REPLACE(@Name, ' ', '</X><X>') + '</X>' AS XML) AS String ) AS A
        CROSS APPLY String.nodes('/X') AS Split(a)

String Agg:

SELECT DISTINCT 
  STUFF((SELECT distinct ' ' + t2.data_field
         from (SELECT Split.a.value('.', 'NVARCHAR(MAX)') AS data_field
                FROM   ( SELECT CAST('<X>' + REPLACE(@Name, ' ', '</X><X>') + '</X>' AS XML) AS String ) AS A
                       CROSS APPLY String.nodes('/X') AS Split(a)) t2

            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,0,'') data
...