web-dev-qa-db-ja.com

SSIS-フラットファイルは常にANSIでUTF-8でエンコードされない

かなり単純なSSISパッケージを用意します。

  • ビューを介してデータを取得するOLE DBソース(dbテーブルnvarcharまたはncharのすべての文字列列)。
  • 既存の日付をフォーマットしてデータセットに追加するための派生列(データ型DT_WSTR)。
  • データセットを分割するマルチキャストタスク:
    • 「処理済み」として行を更新するOLE DBコマンド。
    • フラットファイルの宛先-接続マネージャーがコードページ65001 UTF-8およびUnicodeに設定されているチェックボックスがオフになっています。すべての文字列列はDT_WSTRにマップされます。

このパッケージを実行するたびに、Notepad ++のANSIでフラットファイルを開きます。UTF-8は使用しません。 Unicodeオプションをチェックすると、ファイルはUCS-2リトルエンディアンです。

私は何か間違っていますか?フラットファイルをUTF-8でエンコードするにはどうすればよいですか?

ありがとう

17
Neil

OK- SQL Serverフォーラム で許容できる回避策を見つけたようです。基本的に、2つのUTF-8テンプレートファイルを作成し、ファイルタスクを使用してそれらを宛先にコピーし、上書きではなくデータを追加していることを確認する必要がありました。

0
Neil

ソース-> Advance Editor-> Component Properties-> Set Default Code Page to 65001 AlwaysUseDefaultCodePage to True

次に、Source-> Advance Editor-> InputおよびOutPutプロパティで、外部列とOutPut列の各列をチェックし、可能な限り、CodePageを65001に設定します。

それでおしまい。

ちなみに、Excelはファイル内のデータをUTF-8として定義できません。Excelは単なるファイルハンドラーです。メモ帳を使用してcsvファイルを作成することもできます。 csvファイルにUTF-8を入力する限り、問題ありません。

26
Mirav Rathod

私は最近、次のような状況に遭遇する問題に取り組みました。

SQL Server Integration Services(Visual Studio 2005)を使用したソリューションに取り組んでいます。データベースからデータをプルし、結果をUTF-8形式のフラットファイル(.CSV)に配置しようとしています。このソリューションでは、コードページとして65001を使用しているため、データを完全にエクスポートし、特殊文字をファイルに保持します。

ただし、テキストファイルを開くか、別のプロセスにロードしようとすると、ファイルはUTF-8ではなくANSIであると表示されます。ファイルをメモ帳で開き、[名前を付けて保存]を実行してエンコードをUTF-8に変更すると、外部プロセスは機能しますが、これは面倒な手作業です。

フラットファイル接続マネージャーのコードページプロパティを指定すると、UTF-8ファイルが生成されることがわかりました。ただし、バイトオーダーマークと呼ばれるものがない、UTF-8ファイルのバージョンが生成されます。

したがって、文字AAを含むCSVファイルがある場合、UTF8のBOMは0xef、0xbb、0xbfになります。ファイルにはBOMがありませんが、それでもUTF8です。

残念ながら、一部の古いレガシーシステムでは、アプリケーションはBOMを検索してファイルのタイプを判別します。プロセスも同じように動作しているようです。

この問題を回避するには、エクスポートプロセスの後に実行できるスクリプトタスクで次のコードを使用できます。

using System.IO;

using System.Text;

using System.Threading;

using System.Globalization;

enter code here

static void Main(string[] args)
       {
           string pattern = "*.csv";
           string[] files = Directory.GetFiles(@".\", pattern, SearchOption.AllDirectories);
           FileCodePageConverter converter = new FileCodePageConverter();
           converter.SetCulture("en-US");
           foreach (string file in files)
           {
               converter.Convert(file, file, "Windows-1252"); // Convert from code page Windows-1250 to UTF-8  
           }  
       }

class FileCodePageConverter 
  { 
      public void Convert(string path, string path2, string codepage) 
      { 
          byte[] buffer = File.ReadAllBytes(path); 
          if (buffer[0] != 0xef && buffer[0] != 0xbb) 
          { 
              byte[] buffer2 = Encoding.Convert(Encoding.GetEncoding(codepage), Encoding.UTF8, buffer); 
              byte[] utf8 = new byte[] { 0xef, 0xbb, 0xbf }; 
              FileStream fs = File.Create(path2); 
              fs.Write(utf8, 0, utf8.Length); 
              fs.Write(buffer2, 0, buffer2.Length); 
              fs.Close(); 
          } 
      } 

      public void SetCulture(string name) 
      { 
          Thread.CurrentThread.CurrentCulture = new CultureInfo(name); 
          Thread.CurrentThread.CurrentUICulture = new CultureInfo(name); 
      } 
  }

パッケージを実行すると、指定されたフォルダー内のすべてのCSVが、バイトオーダーマークを含むUTF8形式に変換されます。

このようにして、外部プロセスはエクスポートされたCSVファイルを処理できます。

特定のフォルダのみを探している場合は、その変数をスクリプトタスクに送信し、以下の変数を使用します。

      string sPath;

      sPath=Dts.Variables["User::v_ExtractPath"].Value.ToString();

      string pattern = "*.txt";

      string[] files = Directory.GetFiles(sPath);

これが役に立てば幸いです!!

5

回答に説明を追加しています...

codePageを65001に設定します(ただし、ファイルソースのUnicodeチェックボックスをオンにしないでください)と、UTF-8ファイルが生成されます。 (はい、内部的にはデータ型もnvarcharなどでなければなりません)。

ただし、SSISから作成されたファイルにはBOMヘッダー(バイトオーダーマーカー)がないため、一部のプログラムでは、ファイルがUTF-8ではなくASCIIであると想定します。これは [〜#〜] msdn [〜#〜] でMSの従業員によって確認され、テストによって確認されました。

ファイル追加ソリューションはこれを回避する方法です。適切なBOMを使用して空のファイルを作成し、SSISからデータを追加すると、BOMヘッダーはそのまま残ります。 SSISにファイルを上書きするように指示すると、BOMも失われます。

ここでヒントをありがとう、それは私が上記の詳細を理解するのに役立ちました。

5
Kristi Bittner