0

我有已导入我们的 SQL Server 2008 数据库(使用排序规则)的内容,这些内容在列SQL_Latin1_General_CP1_CI_AS中被 UNICODE NULLS 污染。nvarchar(128)

其影响是当我们的 java 库尝试导出 PDF 报告中的内容和其他此类操作时,它会炸毁我们的 Java 库。

我正在尝试查找和修改各种表和列中的值。我们的一些员工告诉我,违规值看起来像'u s e r n a m e'而不是'username'.

在试图找到这些有问题的 UNICODE NULLS 时,我运行了以下 SQL:

SELECT name 
FROM users
WHERE name LIKE '%[^ -~]%' COLLATE Latin1_General_BIN

返回的是以下集合:

M
M
M
N
S
S
S
S
ÿþA

我认为这些单字母值可能后跟 UNICODE NULLS,但我不确定。最后一个看起来也很可疑。

是否有某种使用方法CONVERT和十六进制值——0x00 来定位字符串中的 UNICODE NULLS nvarchar

编辑#1:

select name, CAST(RIGHT(name,1) AS varbinary(128)) AS RIGHTER_1,
from users
where id=1

returns:

B   0x4200

所以,那个字母“B”有点好笑。这里确实有 UNICODE NULLS,并且这些库的架构不是为了处理 UNICODE。它们使用 LATIN UTF8 字符坚如磐石。

4

3 回答 3

0

尝试使用 varbinary 转换查找空 unicode 字符序列可能会导致误报,例如 UTF16 LE 中的以下 unicode:

20 00 00 A0

该字符串是一个空格,后跟一个 Unicode 字符 A0。两者都是有效的非空字符。但是,如果您这样做:

where charindex (0x0000, cast(UnicodeText as varbinary (max))) > 0

您会在空格结尾和下一个字符的开头之间得到误报。

这是我写的一个函数。请注意,它在处理大文本时表现不佳,我正在努力改进。可能 CLR proc 会更好地工作。尝试这个:

    create function dbo.FindNullUnicode
(
    @Input nvarchar(max)
    ,@StartPosition bigint = 1
)
returns bigint
as
begin
    if @StartPosition < 1
        set @StartPosition = 1;

    declare @pos bigint = @StartPosition;
    declare @len bigint = len(@Input);
    declare @singlechar nchar(1);

    while (@pos <= @len)
    begin
        if unicode(SUBSTRING(@input,@pos,1)) = 0 
            return @pos;

        set @pos +=1;
    end;
    return 0;
end
于 2013-10-21T19:40:21.583 回答
0
于 2013-10-21T19:55:15.263 回答
-1

您可以使用CAST(name AS varbinary(128))将值查看为十六进制并检查它。

您可以使用 condition 找到“空字符” name LIKE '%'+CHAR(0)+'%',但是,有效的 unicode 字符串也可能包含零,因此这可能不是您需要做的。

您确定问题不在您的库或 PDF 生成器中吗?看起来您在数据库中有 unicode 字符串,但应用程序将它们解释为 ASCII 字符串。

于 2013-01-15T09:00:32.930 回答