0

SQL Server 2008 データベースに ( collat​​ion を使用して) インポートされたコンテンツがありSQL_Latin1_General_CP1_CI_AS、列に UNICODE NULLS が含まれてnvarchar(128)います。

その影響は、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

これらの 1 文字の値の後に UNICODE NULLS が続く可能性があると思いますが、確かなことはわかりません。最後のものも確かに疑わしいように見えます。

CONVERT文字列内の UNICODE NULLS を見つけるために、16 進値 -- 0x00 を使用する方法はあり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 変換を使用して null の Unicode 文字シーケンスを検索しようとすると、誤検出が発生する可能性があります。たとえば、UTF16 LE の次の unicode です。

20 00 00 A0

文字列は、スペースの後に Unicode 文字 A0 が続きます。どちらも有効な非ヌル文字です。ただし、これを行った場合:

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

スペースの終わりと次の文字の始まりの間で誤検知が発生します。

ここに私が書いた関数があります。大きなテキストではうまく機能しないことに注意してください。これは改善に取り組んでいます。おそらく、CLR プロシージャの方がうまくいくでしょう。これを試して:

    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

元の投稿が 9 か月以上前のものであることを考えると、これはポスターには遅すぎると確信しています。ただし、ドキュメントによると、ncharおよびnvarcharデータ型Unicode です。それらは次のように定義されます。

| | 固定長または可変長のUnicode データであり、UNICODE UCS-2 文字セットを使用する文字列データ型。ncharnvarchar

UCS-2は、列の各文字が 2 バイトを占めることを意味します。データが 1 バイト文字の場合、上位バイトは当然 0x00 になり、1 オクテットおきに 0x00 になります。

当初の問題は、消費者がほぼ確実に UCS-2/UTF-16 ではなく ASCII または UTF-8 データを期待していたことでした。charほとんどの場合、列は/varcharではなくnchar/として宣言されているはずnvarcharです。適切な解決策は、次のいずれかを実行することです。

  • 列が正しいデータ型になるようにテーブルを変更します
  • convert()関数を使用して列を変換するようにクエリを変更すると、次のようになります。convert(varchar(4000),my_nvarchar_column)
  • コンシューマーを変更して、2 バイト文字を適切に使用できるようにします。
于 2013-10-21T19:55:15.263 に答える
-1

CAST(name AS varbinary(128))値を16進数として表示し、調べるために使用できます。

条件を使用して「ヌル文字」を見つけることができますがname LIKE '%'+CHAR(0)+'%'、有効なUnicode文字列にもゼロが含まれる可能性があるため、これはおそらく必要なことではありません。

問題がライブラリやPDFジェネレーターにないことを確認しますか?データベースにUnicode文字列があるように見えますが、アプリケーションはそれらをASCII文字列として解釈しています。

于 2013-01-15T09:00:32.930 に答える