特殊字符-SQL

时间:2019-06-07 13:01:47

标签: sql sql-server special-characters

如何在SqlServer的列中获取特殊字符?

我有电子邮件列表,而且我必须找到特殊的角色,例如波纹管

**Email** 
JóhnSnow@gmail.com
Khãlessi@gmail.com 
  

如您在上面看到的,有''和'´'作为特殊字符。可能会出现其他字符,例如“ .. ”或其他。

我正在Sql Server 2012上工作,

有人建议解决吗?

1 个答案:

答案 0 :(得分:4)

要提取特殊字符,您首先需要将字符串分成几行,以便可以分别查询每个字符,您可以使用数字表进行查询。如果您没有,则可以轻松创建它们:

WITH N1 AS (SELECT N FROM (VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) n (N)),
N2 (N) AS (SELECT 1 FROM N1 AS N1 CROSS JOIN N1 AS N2),
N3 (N) AS (SELECT 1 FROM N2 AS N1 CROSS JOIN N2 AS N2),
Numbers (Number) AS (SELECT ROW_NUMBER() OVER(ORDER BY N) FROM N3)
SELECT  Number
FROM    Numbers;

这给出了1-10000之间的数字列表。有关here的更多信息。

然后,您可以使用条件Number < LEN(Email)将其连接到数据,以确保您为电子邮件中的每个字符返回上一行,然后使用SUBSTRING()提取位置{{1 }}:

n

哪个给:

DECLARE @T TABLE (ID INT IDENTITY, Email NVARCHAR(255));
INSERT @T (Email)
VALUES (N'JóhnSnów@gmail.com'), (N'Khãlessi@gmail.com'), ('NedStark@gmail.com');

WITH N1 AS (SELECT N FROM (VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) n (N)),
N2 (N) AS (SELECT 1 FROM N1 AS N1 CROSS JOIN N1 AS N2),
N3 (N) AS (SELECT 1 FROM N2 AS N1 CROSS JOIN N2 AS N2),
Numbers (Number) AS (SELECT ROW_NUMBER() OVER(ORDER BY N) FROM N3)
SELECT  t.ID, 
        t.Email, 
        Character = SUBSTRING(t.Email, n.Number, 1)
FROM    @T AS t
        INNER JOIN Numbers n    
            ON n.Number < LEN(t.Email)
ORDER BY t.ID;

然后,您可以通过使用归类ID Email Character ----------------------------- 1 JóhnSnow@gmail.com J 1 JóhnSnow@gmail.com ó 1 JóhnSnow@gmail.com h 1 JóhnSnow@gmail.com n 1 JóhnSnow@gmail.com S 1 JóhnSnow@gmail.com n 1 JóhnSnow@gmail.com ó 1 JóhnSnow@gmail.com w ..... 将特殊字符转换为VARCHAR并将其检查为原始字符来提取特殊字符:

SQL_Latin1_General_Cp1251_CS_AS

结果

DECLARE @T TABLE (ID INT IDENTITY, Email NVARCHAR(255));
INSERT @T (Email)
VALUES (N'JóhnSnów@gmail.com'), (N'Khãlessi@gmail.com'), ('NedStark@gmail.com');

WITH N1 AS (SELECT N FROM (VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) n (N)),
N2 (N) AS (SELECT 1 FROM N1 AS N1 CROSS JOIN N1 AS N2),
N3 (N) AS (SELECT 1 FROM N2 AS N1 CROSS JOIN N2 AS N2),
Numbers (Number) AS (SELECT ROW_NUMBER() OVER(ORDER BY N) FROM N3),
AllCharacters as
(   SELECT  t.ID,  
            t.Email, 
            Character = SUBSTRING(t.Email, n.Number, 1), 
            Position = n.Number
    FROM    @T AS t
            INNER JOIN Numbers n    
                ON n.Number < LEN(t.Email)
)
SELECT  ac.ID, ac.Character, ac.Position
FROM    AllCharacters AS ac
WHERE   CONVERT(CHAR(1), ac.Character) COLLATE SQL_Latin1_General_Cp1251_CS_AS <> ac.Character
ORDER BY ac.ID;

最后,如果需要,您可以将XML extensions to concatenate这些字符用于单个列:

ID  Email                   Character   Position
----------------------------------------------------
1   JóhnSnów@gmail.com          ó           2
1   JóhnSnów@gmail.com          ó           7
2   Khãlessi@gmail.com          ã           3

结果

DECLARE @T TABLE (ID INT IDENTITY, Email NVARCHAR(255));
INSERT @T (Email)
VALUES (N'JóhnSnów@gmail.com'), (N'Khãlessi@gmail.com'), ('NedStark@gmail.com');

WITH N1 AS (SELECT N FROM (VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) n (N)),
N2 (N) AS (SELECT 1 FROM N1 AS N1 CROSS JOIN N1 AS N2),
N3 (N) AS (SELECT 1 FROM N2 AS N1 CROSS JOIN N2 AS N2),
Numbers (Number) AS (SELECT ROW_NUMBER() OVER(ORDER BY N) FROM N3),
AllCharacters as
(   SELECT  t.ID,  
            t.Email, 
            Character = SUBSTRING(t.Email, n.Number, 1), 
            Position = n.Number
    FROM    @T AS t
            INNER JOIN Numbers n    
                ON n.Number < LEN(t.Email)
), SpecialCharacters AS
(   SELECT  ac.ID, ac.Character, ac.Position
    FROM    AllCharacters AS ac
    WHERE   CONVERT(CHAR(1), ac.Character) COLLATE SQL_Latin1_General_Cp1251_CS_AS <> ac.Character
)
SELECT  t.ID,
        t.Email,
        SpecialCharacters = ISNULL(STUFF(s.SpecialCharacterList.value('.', 'NVARCHAR(255)'), 1, 2, ''), '')
FROM    @T AS T
        CROSS APPLY
        (   SELECT  CONCAT(N', ', s.Character, '(', Position, ')')
            FROM    SpecialCharacters AS s
            WHERE   s.ID = t.ID
            ORDER BY Position
            FOR XML PATH(''), TYPE
        ) s (SpecialCharacterList)
ORDER BY ID;

顺便说一句,它可能更适合于您在表中存储算作特殊字符的需求,而不是依赖于代码页进行特定的校对,如果您要这样做,则只需进行更改这行:

ID  Email                   SpecialCharacters
------------------------------------------------
1   JóhnSnów@gmail.com      ó(2), ó(7)
2   Khãlessi@gmail.com      ã(3)
3   NedStark@gmail.com  

针对:

WHERE   CONVERT(CHAR(1), ac.Character) COLLATE SQL_Latin1_General_Cp1251_CS_AS <> ac.Character