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


8

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

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

したがって、私の質問は、SQL Serverがこの文字を「パイプ、壊れた垂直バー」であるASCIIコード166に変換するのはなぜ¦ですか。

SELECT NCHAR(9619), CAST(NCHAR(9619) AS CHAR(1)), ASCII(CAST(NCHAR(9619) AS CHAR(1)))

3
SQL Serverは、このペーパーでホモグリフ変換と呼んでいるものを使用し表現できない文字をほぼ同等のものに変換します。たとえば、文字のアクセントを失うか、スマートクォートをプレーンクォートに変更します。私はそれがあまりよく見えないことに同意します!これらの変換が文書化されているかどうか、またはどこに文書化されているかはわかりません。
マーティンスミス

うわー、わからなかった...うわあ、ただ正しくないようだ...同じキャラクターではない。"...おっと、このコードページにそのような文字は見つかりません..."だけで変換に失敗するのはなぜですか。
ヘンリーリー

1
このページを読んで、これを思い出しました。SQL Serverがまったく同じ「最適な」アルゴリズムを使用しているかどうかは不明です。
マーティンスミス

1
SQL Serverの「最適な」マッピングがわからない場合の@MartinSmithは、これらのマッピングを見つけたので、以下の私の回答を参照してください:-)。
ソロモンルツキー2015年

回答:


8

SQLがUnicode 9619をASCIIコード166に変換する理由

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

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

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

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

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

SQL Serverスタックトレース


7

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

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

しかし、これらのマッピングは正確には何ですか?そのMSDNのページには、使用次のことを述べること:

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

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

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

最適な戦略は詳細に文書化されていません。ただし、いくつかのコードページがUnicodeコンソーシアムの 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番目の質問に対する答えが「いいえ」であることも示します(つまり、マップされていないコードポイントは、「不明」の文字以外に変換されません)。したがって、そのマッピングファイルは非常に正確です:-)。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.