2012-05-11 13 views
3

現在、Delphi 2007のすべてのコードベースをDelphi XE2に更新中です。最大の考慮点は、すべての基本型(char/string)をANSI型(ansichar/ansistring)に再定義することで対処したANSIからUnicodeへの変換です。これは私がデータベースで作業を始めるまで、私たちのプログラムの多くで働いていました。Unicode変換、データベースの不具合(Delphi 2007 to XE2)

この問題は、ファイルから読み込んだ情報をSQL Server 2008データベースに格納するプログラムを変換したときに開始されました。以下のようなデータが失敗する検索する文字列を使用突然単純なクエリ、:

SELECT id FROM table WHERE name = 'something' 

nameフィールドがvarcharです。文字列名の前にNという接頭辞を付けて、クエリを正常に完了できたことがわかりました。私は印象の下にあったvarcharだけがANSI文字を格納することができましたが、それはUnicodeを格納しているようですか?

さらに詳しい情報:デルファイの名前フィールドはstring[13]ですが、私は[13]を削除しようとしました。データベース照合順序はSQL_Latin1_General_CP1_CI_ASです。私たちはデータベースとのインターフェイスにADOを使用します。接続情報はODBCアドミニストレーターに保管されます。

注:私はPanagiotisからの少しのおかげで実際の問題を解決しました。マップファイルから読み込んだ名前はarray[1..24] of AnsiCharです。この値は暗黙的にヌル文字を含むstring[13]に変換されていました。そのため、5文字の名前がデータベースに5文字+ 8文字として実際に格納されていました。

答えて

2

varcharフィールドには、Unicode文字は格納されません。フィールドの照合順序で指定されたコードページにASCII値を格納します。異なるコードページのUnicodeまたはデータを格納しようとすると、SQL Serverはtry to convert charactersを正しいコードページに変換します。この機能を無効にすることもできますが、アプリケーションでのnvarcharフィールドとUnicodeStringを使用することで、混乱を避けることができます。

アプリケーションのUNICODEタイプではなく、すべての文字タイプをANSIに変更すると言います。ユニコードを使用する場合は、UnicodeStringのようなユニコードタイプを使用する必要があります。さもなければあなたの値はあなたのサーバーに送られるときにANSIに変換されます。この変換は、サーバーに送信されるAnsiStringを作成するときにコードによって行われます。

ところで、selectステートメントはASCII値をフィールドに格納します。あなたはUnicode値としてそれを保存したい場合でも、これはあなたのデータがUnicode形式でサーバーに到達することを保証するものではありません

SELECT id FROM table WHERE name = N'something' 

をeg.g、Nと価値を付加する必要があります。 AnsiStringにステートメントを格納すると、ステートメント全体がANSIに変換されてからサーバーに送信されます。あなたのアプリが間違った変換をした場合、あなたはサーバー上のマングルされたデータで終わるでしょう。

ソリューションは非常に簡単です。パラメータ化された文を使用して、ユニコード値をユニコードパラメータとして渡し、それらをNVARCHARフィールドに格納するだけです。はるかに高速で、すべての変換エラーを回避し、SQLインジェクション攻撃を防ぎます。

+0

残念ながら、私は変更できるものによって非常に制限されています。私は完全にUnicodeを取り入れたいと思っていますが、システムの半分はVisual C++ 4.2で書かれています。私たちはまた、真のUnicode変換が精巧に可能ではない非常に複雑なシステムといくつかのコードを共有しています。あなたが言ったことを踏まえて、問題がどこで発生しているかをより正確に診断しようと思います。 –