在我的代码中,我需要以某种指定的格式显示名称,在该格式中,每个字符都应替换为“ *”字符。但是,我不必替换空格。
现在,由于它是日语应用程序,因此名称也可以包含日语空间字符。有什么可以帮助我识别空间字符的通用方法。 我所做的是在fiddle中。
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);
答案 0 :(得分:2)
考虑到所有具有空格属性here的字符,必要的查询可能如下所示:
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在线进行测试。
答案 1 :(得分:0)
这可以在SQL2017中轻松完成。
DECLARE @Name NVARCHAR(50) = N'中山 大地';
SELECT STRING_AGG(replicate('*', LEN(value)), ' ') AS obfuscated
FROM STRING_SPLIT(@name, ' ')
STRING_SPLIT SQL2016
STRING_AGG SQL2017
但是对于旧版SQL Server,这可能会更具挑战性。
字符串拆分:
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)
字符串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