我正在使用一个旧数据库,其中有人在将数据插入数据库之前没有正确编码数据。这导致文本像
“错误的t xt”(在我的情况下,' '是ø)。
我正在寻找一种方法来查找列包含这样的数据的所有行,所以我可以纠正它。
到目前为止我尝试使用正则表达式
SELECT * FROM table WHERE ([colm] not like '[a-zA-Z\s]%')
但无论我做什么,我都找不到只选择含有' '的方法
像搜索一样
SELECT * FROM table WHERE ([colm] like '%�%')
也不会退货。 (尝试过,只是在案件中)。
我一直在Google和Stackoverflow上搜索这个,但是没有人遇到这个问题,或者我在寻找错误的东西。
所以,如果有人能帮助我,我会非常高兴。
谢谢你的时间。
假设字符串中的字符确实是U+FFFD REPLACEMENT CHARACTER
( ),并且它不显示为替换字符,因为其中实际上有其他字节无法正确解码,您可以找到它
SELECT * FROM table WHERE [colm] LIKE N'%�%' COLLATE Latin1_General_BIN2
或者(以避免编码重整字符的任何进一步问题)
SELECT * FROM table WHERE [colm] LIKE N'%' + NCHAR(0xfffd) + N'%' COLLATE Latin1_General_BIN2
Unicode是必需的,因为 在任何单字节排序规则中都不存在,并且需要二进制排序规则,因为常规排序规则将treat视为根本不在字符串中出现。
试试这个:
WHERE [colm] not like N'%[a-zA-Z]%'
当然,这应该返回带有数字,空格和标点符号的值。
正如Jeroen所说,使用binary
似乎是要走的路。我个人建议在这里使用NGrams4k
,但我建立了一个快速计数表,而不是完成这项工作:
WITH N AS(
SELECT N
FROM (VALUES(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL)) N(N)),
Tally AS(
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS I
FROM N N1, N N2, N N3, N N4)
SELECT V.Colm
FROM (VALUES(N'Wrong t�xt" (in my case the ''�'' is a ø)'),
(N'This string is ok'))V(colm)
JOIN Tally T ON LEN(V.Colm) >= T.I
CROSS APPLY (VALUES(SUBSTRING(V.Colm,T.I,1))) SS(C)
GROUP BY V.colm
HAVING COUNT(CASE CONVERT(binary(2),SS.C) WHEN 0xFDFF THEN 1 END) > 0;
您可以替换U+FFFD REPLACEMENT CHARACTER
( )的出现次数并将其与原始值进行比较:
SELECT *
, CASE WHEN CONVERT(VARBINARY(MAX), t.colm) = CAST(REPLACE(CONVERT(VARBINARY(MAX), t.colm), 0xFDFF, 0x) AS VARBINARY(MAX)) THEN 1 ELSE 0 END AS EncodingCorrect
FROM (
SELECT N'Wrong t�xt" (in my case the ''�'' is a ø)' AS colm
UNION ALL
SELECT 'Correct text'
UNION ALL
SELECT 'Wrong t?xt" (in my case the ''?'' is a ø)'
) t
@Jeroen Mostert的建议WHERE colm LIKE N'%�%' COLLATE Latin1_General_BIN2
似乎是更好,更易读的解决方案。