web-dev-qa-db-ja.com

SSISを介した漢字のインポート

漢字を含むファイルをテーブルにインポートしようとしています。ファイルエンコーディングはBig5(Traditional)です。

以下は、インポートする必要があるようなサンプルファイルです。 https://www.pastiebin.com/5d7782d9b63fa

ファイルをインポートする必要があるテーブルには、次のような構造があります。

create table dbo.Test (
      AccountId   numeric(18, 0) not null
    , Province    nvarchar(50)       null
    , City        nvarchar(50)       collate Chinese_Hong_Kong_Stroke_90_CI_AI
    , Country     nvarchar(50)       null
    , Gender      nvarchar(50)       null
)

OPENROWSET/BULKを使用してインポートすると、すべてのデータが正しく転送されます。

select AccountId, Province, City, Country, Gender
from openrowset (
      bulk 'C:\chinese_sample.dat'
    , firstrow = 1
    , formatfile = 'C:\chinese_sample.xml'
) t

これが私が使用するフォーマットファイルです: https://www.pastiebin.com/5d7783396f9e4

enter image description here


しかし、SSISを使用してファイルをインポートしようとすると、中国語の文字が正しく解析されません。

フラットファイルソースでは、DataType文字列[DT_STR]とCodePage 950を使用します。次に、それをUnicode文字列[DT_WSTR]に変換します。

enter image description here

テキストがテーブルにインポートされる方法は次のとおりです。

enter image description here

ご覧のとおり、一部の文字は正しく解析され、一部の文字は正しく解析されていません。何が欠けていますか?

4
GriGrim

問題は、正しくインポートされていない行に、コードページ950でエンコードされ、末尾のバイトが0x7Cである文字が含まれていることです。これは有効ですbutは、たまたま区切り記号として使用しているパイプ記号でもあります。例えば:

SELECT CONVERT(VARBINARY(20), CONVERT(VARCHAR(20), N'四會'
                                      COLLATE Chinese_Hong_Kong_Stroke_90_CI_AI));
-- 0xA57C B77C

これらの2つの文字のそれぞれの末尾バイトは0x7Cです。パーサーは、コードページ950文字の2バイトシーケンスの一部ではなく、区切り文字としてそれを表示しているようです。これが、「?」を取得する理由です。 「City」と「Country」の両方で、「Gender」列に残りの入力行があります。 「?」これらの2つの列の先頭のバイト0xA50xB7は、それ自体では有効でないためです。

次の行にも同じ問題があります。

SELECT CONVERT(VARBINARY(20), CONVERT(VARCHAR(20), N'元朗大坑|'
                              COLLATE Chinese_Hong_Kong_Stroke_90_CI_AI))
-- 0xA4B8 AED4 A46A A77C 7C

今回は、 "City"値の最後に来る区切り文字を保持しました(そのため、区切り文字が4番目の文字の後続バイトと同じバイト値であることが明確になります)。 4番目の文字は、コードページ950では0xA77Cとしてエンコードされます。これが、4番目の文字だけが "?"と表示される理由です。

したがって、これはmightがSSISのバグである可能性があります。または、構成の問題である可能性があります。この1列だけでなく、ファイル全体がコードページ950であることを示す方法はありますか?テキストファイルの観点から列ごとにコードページを扱うことは意味がありません。ファイル全体は、その1つの列だけでなく、コードページ950としてエンコードされます。役立つデリミタを変更することは可能ですが、デリミタは2バイト文字の有効な後続バイト値としてエンコードできるため、問題が遅延する可能性があります。 OPENROWSETが正しく機能することを考えると、これもcanであると信じる必要があります(ただし、OPENROWSETのファイルのエンコーディングを設定していませんが、列だけなので、これはまだSSISバグである可能性があります)。

SSIS内でファイルのエンコーディングを設定するには、以下を試してください。

  1. Flat File Connection Manager Editor(General Page) に移動します
  2. [コードページ]で、950と入力します。
  3. 「Unicode」が選択されていないことを確認してくださいが選択されていません。

また、「出力列」の下の「CITY」列を確認し、「Fast Parse」ではなく 「Standard Parse」 を使用していることを確認します(「Fast Parse」はロケールに依存しないため)。

2
Solomon Rutzky