web-dev-qa-db-ja.com

Unicodeを非Unicodeに変換するときの自動変換/ NVARCHARからVARCHAR

Unicodeコードポイント9619は、「ダークシェード」と呼ばれる文字です:__( http://unicode-table.com/en/search/?q=9619 )。

_SQL_Latin1_General_CP1_CI_AS_照合と1252コードページを使用すると、コードページ1252が表示されないため、そのUnicode文字を非Unicodeデータ型にキャスト/変換すると疑問符(_?_)が発生することが予想されます。この文字が含まれていて、変換を実行できない場合のSQL Serverの動作のようです。

だから私の質問です:SQL Serverはなぜこの文字をASCIIコード166に変換します。これは "パイプ、縦棒が壊れている"です:_¦_?

_SELECT NCHAR(9619), CAST(NCHAR(9619) AS CHAR(1)), ASCII(CAST(NCHAR(9619) AS CHAR(1)))
_
8
Henry Lee

SQLがUnicode 9619をASCIIコード166に変換するのはなぜですか?

SQL Serverは、ここでは特別なカスタムロジックを採用していません。標準のオペレーティングシステムサービスを使用して変換を実行しています。

具体的には、SQL Serverタイプおよび式サービス(sqlTsEs)がkernel32.dllのOSルーチン WideCharToMultiByte を呼び出します。 SQL Serverは、ルーチンが「クイック変換」を実行するように、入力パラメーターをWideCharToMultiByteに設定します。これは、直接変換が存在しない場合に特定のデフォルト文字の使用を要求するよりも高速です。

クイック翻訳は、ターゲットコードページに依存して、 -マーティンスミスが提供したリンク の質問へのコメントで述べられているように、一致しない文字に対して最適マッピングを実行します。

最適な方法はコードページによって異なり、詳細は文書化されていません。

入力パラメーターが迅速な変換用に設定されている場合、WideCharToMultiByteはOSサービスGetMBNoDefaultsource )を呼び出します。質問で指定された変換を実行するときにSQL Serverコールスタックを検査すると、これが確認されます。

SQL Server stack trace

8
Paul White 9

Unicodeデータから特定のコードページへの変換では、「ベストフィット」戦略と呼ばれる方法が採用されます(@Paulの answer と、@ Martinが質問のコメントに記載したリンクに記載されています)。 。そのMSDNページによると 。NET Frameworkの文字エンコーディング

最適マッピングは、UnicodeデータをコードページデータにエンコードするEncodingオブジェクトのデフォルトの動作です...

しかし、これらのマッピングは正確には何ですか?そのMSDNページ中古次のように記述します。

最適な方法はコードページによって異なり、詳細は文書化されていません。

しかし、それは完全に正しくはありませんでした。おそらく、マッピングを決定するための「戦略」は正確に文書化されていません。 OK。ただし、マッピング自体あるは文書化されており、見つけるのが最も簡単な場所ではありません。

したがって、MicrosoftがドキュメントをGitHubに移動したおかげで、そのページには次のように記載されています(私が更新したためです????)。

最適な戦略は詳細に文書化されていません。ただし、いくつかのコードページが nicode Consortium's Webサイトに記載されています。マッピングファイルの解釈方法の説明については、そのフォルダー内のreadme.txtファイルを確認してください。

次のURLにアクセスすると、いくつかのファイルのリストが表示されます。各ファイルには、Unicode文字をマッピングするコードページの名前が付けられています。

ftp://ftp.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WindowsBestFit/

ほとんどのファイルは2006-10-04に最後に更新(または少なくともそこに配置)され、そのうちの1つは2012-03-14に更新されました。これらのファイルの最初の部分は、ASCIIコードを同等のUnicodeコードポイントにマッピングします。しかし、各ファイルの2番目の部分は、Unicode文字をASCII "同等のものにマッピングします」.

SQL Serverがこれらのマッピングを本当に使用しているかどうかを確認するために、コードページ1252マッピングを使用するテストスクリプトを作成しました。これは、次の2つの質問に答えることで判断できます。

  1. すべてのマップされたコードポイントについて、SQL Serverはそれらを指定されたマッピングに変換しますか?
  2. マップされていないすべてのコードポイントについて、SQL Serverはそれらを「?」以外の文字に変換しますか?

テストスクリプトが長すぎてここに配置できないため、次のURLのPastebinに投稿しました。

SQL ServerでのUnicodeからコードページへのマッピング

スクリプトを実行すると、上記の最初の質問に対する回答が「はい」であることが示されます(つまり、提供されたすべてのマッピングが順守されていることを意味します)。また、2番目の質問に対する答えが「いいえ」であることも示します(つまり、マップされていないコードポイントは、「不明」の文字以外には変換されません)。したがって、そのマッピングファイルは非常に正確です:-)。

7
Solomon Rutzky