Подтвердить что ты не робот

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 Little Endian.

Я делаю что-то неправильно - как я могу получить плоский файл в кодировке UTF-8?

Спасибо

4b9b3361

Ответ 1

ОК - казалось, нашел приемлемую работу на Форумы SQL Server. По сути, мне пришлось создать два файла шаблона UTF-8, использовать File Task, чтобы скопировать их в пункт назначения, затем убедитесь, что я добавляю данные, а не переписываю.

Ответ 2

В источнике → Предварительный редактор → Свойства компонента → Установить страницу кода по умолчанию на 65001 AlwaysUseDefaultCodePage - True

Затем Source- > Advance Editor → Input And OutPut Properties Проверьте каждую колонку во внешних столбцах и столбцах OutPut и установите CodePage на 65001, где это возможно.

Что это.

Кстати, Excel не может определить данные внутри файла как UTF - 8. Excel - это просто обработчик файлов. Вы также можете создавать файлы csv с помощью блокнота. до тех пор, пока вы заполняете файл csv с помощью UTF-8, вы должны быть в порядке.

Ответ 3

Добавление объяснений к ответам...

настройка CodePage на 65001 (но НЕ проверяйте флажок Unicode в источнике файла), должен сгенерировать файл UTF-8. (да, внутренние типы данных также должны быть nvarchar и т.д.).

Но файл, созданный из SSIS, не имеет заголовка спецификации (Byte Order Marker), поэтому некоторые программы предполагают, что это все еще ASCII, а не UTF-8. Я видел, что это подтверждено сотрудниками MS на MSDN, а также подтверждено тестированием.

Решение для добавления файлов - это способ создания пустого файла с соответствующей спецификацией, а затем добавления данных из SSIS, заголовок спецификации остается на месте. Если вы сообщите SSIS о перезаписывании файла, он также потеряет спецификацию.

Спасибо за подсказки здесь, это помогло мне разобраться в деталях.

Ответ 4

Недавно я работал над проблемой, когда мы сталкиваемся с такой ситуацией, как:

Вы работаете над решением, использующим службы интеграции SQL Server (Visual Studio 2005). Вы извлекаете данные из своей базы данных и пытаетесь поместить результаты в плоский файл (.CSV) в формате UTF-8. Решение отлично экспортирует данные и сохраняет специальные символы в файле, потому что вы использовали 65001 в качестве кодовой страницы.

Однако текстовый файл, когда вы его открываете или пытаетесь загрузить его в другой процесс, говорит, что файл ANSI вместо UTF-8. Если вы откроете файл в блокноте и сделаете SAVE AS и измените кодировку на UTF-8, а затем ваш внешний процесс будет работать, но это утомительная ручная работа.

Что я обнаружил, что при указании свойства "Кодовая страница" менеджера соединений с плоскими файлами он создает файл UTF-8. Тем не менее, он генерирует версию файла UTF-8, которая пропускает то, что мы называем байтовой меткой заказа.

Итак, если у вас есть файл CSV, содержащий символ AA, спецификация для UTF8 будет 0xef, 0xbb и 0xbf. Хотя файл не имеет спецификации, его еще UTF8.

К сожалению, в некоторых старых устаревших системах приложения ищут спецификацию для определения типа файла. Похоже, что ваш процесс также делает то же самое.

Чтобы обойти эту проблему, вы можете использовать следующий фрагмент кода в своей задаче script, которая может запускаться после процесса экспорта.

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 файлами.

если вы ищете только конкретную папку... отправьте эту переменную в script задачу и используйте ниже одного.

      string sPath;

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

      string pattern = "*.txt";

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

Надеюсь, это поможет!