有没有办法执行数据清理并识别拉丁字符,例如Á(和类似字符(并将它们转换为最接近的美国英语字符(在本例中为"A"(?
我更喜欢直接在 TSQL 代码中执行此操作,但如果不可能,我愿意使用其他选项,例如任何 C# 方法。
https://en.wikipedia.org/wiki/List_of_Unicode_characters
我在一个表中有数十万条记录。 数据条目有这样的错误,这些会导致破坏代码的问题。
谢谢。
更新的 Anwer (20120212(:
虽然我下面的答案会起作用,并且考虑到 T-SQL TRANSLATE 特别快,但上面发布的 gett 和 David 的答案会表现得更好。
值得注意的是(我刚刚了解到这一点(,Cyrillic_General_CI_AI
和Greek_CI_AI
也有效。很高兴知道这一点,因为某些排序规则的性能比其他排序规则更好,因此最好进行测试。
以前的答案
您没有提到您正在使用的SQL Server版本。
如果您使用的是 SQL Server 2017+
然后,您可以像这样利用翻译:
DECLARE @string VARCHAR(100) = 'Thë Quìck Grééñ Fox Jumps ôver The Lázy Dög.';
SELECT NewString = TRANSLATE(@string,accents.C,clean.C)
FROM (VALUES('áÁâÂäÄãÃàÀéÉêÊëËèÈíÍîÎïÏìÌóÓôÔöÖõÕòÒúÚûÛüÜùÙýÝñÑçÇ')) AS accents(C)
CROSS APPLY (VALUES('aAaAaAaAaAeEeEeEeEiIiIiIiIoOoOoOoOoOuUuUuUuUyYnNcC')) AS clean(C);
回归:敏捷的绿狐狸跳过懒狗。
如果您使用的是早期版本的 SQL
为此,您可以利用NGrams8K创建自己的翻译函数,我将该函数包含在本文末尾。
SELECT t.NewString
FROM (VALUES('áÁâÂäÄãÃàÀéÉêÊëËèÈíÍîÎïÏìÌóÓôÔöÖõÕòÒúÚûÛüÜùÙýÝñÑçÇ')) AS accents(C)
CROSS APPLY (VALUES('aAaAaAaAaAeEeEeEeEiIiIiIiIoOoOoOoOoOuUuUuUuUyYnNcC')) AS clean(C)
CROSS APPLY samd.translate8K(@string,accents.C,clean.C) AS t;
以下是我用来生成重音字符字符串的代码:
SELECT CONCAT(
CHAR(225),CHAR(193),CHAR(226),CHAR(194),CHAR(228),CHAR(196),CHAR(227),CHAR(195),CHAR(224),CHAR(192), -- a(10)
CHAR(233),CHAR(201),CHAR(234),CHAR(202),CHAR(235),CHAR(203),CHAR(232),CHAR(200), -- e(8)
CHAR(237),CHAR(205),CHAR(238),CHAR(206),CHAR(239),CHAR(207),CHAR(236),CHAR(204), -- i(8)
CHAR(243),CHAR(211),CHAR(244),CHAR(212),CHAR(246),CHAR(214),CHAR(245),CHAR(213),CHAR(242),CHAR(210), -- o(10)
CHAR(250),CHAR(218),CHAR(251),CHAR(219),CHAR(252),CHAR(220),CHAR(249),CHAR(217), -- u(8)
CHAR(253),CHAR(221),CHAR(241),CHAR(209),CHAR(231),CHAR(199)) -- y(2),n(2),c(2)
自定义翻译功能:
CREATE FUNCTION samd.translate8K
(
@inputString VARCHAR(8000),
@characters VARCHAR(8000),
@translations VARCHAR(8000)
)
RETURNS TABLE WITH SCHEMABINDING AS RETURN
/*****************************************************************************************
[Purpose]: Custom version of SQL Server 2017 Translate
-- Masking possible PII
DECLARE @inputstring VARCHAR(8000) =
'I don''t know if you got my SSN but it''s 555-90-5511. Call me at 312.800.5555';
SELECT t.newstring
FROM samd.translate8K(@inputString, '0123456789', REPLICATE('#',10)) AS t;
[Revision History]:
------------------------------------------------------------------------------------------
Rev 00 - 20180725 - Initial Development - Alan Burstein
****************************************************************************************/
SELECT newstring =
(
SELECT CASE WHEN c.chr>c.tx THEN '' WHEN c.chr>0 THEN t.chr ELSE ng.token END+''
FROM samd.NGrams8k(@inputString,1) AS ng
CROSS APPLY (VALUES(CHARINDEX(ng.token, @characters),LEN(@translations))) AS c(chr,tx)
CROSS APPLY (VALUES(SUBSTRING(@translations,c.chr,1))) AS t(chr)
ORDER BY ng.position
FOR XML PATH(''), TYPE
).value('text()[1]', 'varchar(8000)');
GO
https://emw3.com/unicode-accents.html
参考:(感谢评论中的@gotqn( stackoverflow.com/a/12715102/1080354
SELECT 'héllö! this is à test!' Collate SQL_Latin1_General_CP1253_CI_AI
结果:
hello! this is a test!