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

Почему SSIS не распознает строковый разделитель строк строки {LF} при импорте плоского файла UTF-8?

Я пытаюсь импортировать данные из плоского файла с кодировкой utf-8 в SQL Server 2008 с использованием SSIS. Это то, что конец данных строки выглядит как в Notepad ++:

enter image description here

У меня есть еще несколько изображений, показывающих, как выглядит диспетчер соединений файлов:

enter image description here

enter image description here

Вы можете видеть, что данные отображаются правильно в предварительном просмотре диспетчера подключений файлов. Когда я пытаюсь импортировать эти данные, импорт строк не выполняется. Я получаю сообщение об ошибке, указывающее, что разделитель строк не найден. На изображениях диспетчера подключений файлов вы можете видеть, что разделитель строки заголовка и разделитель строк установлены на {LF}. Этого было достаточно для создания правильного предварительного просмотра, поэтому я проиграл, почему он не работал для импорта. Я пробовал ряд вещей, которые принесли нулевые результаты:

  • Пробовал использовать импорт мастера в SSMS... те же результаты
  • Пробовал использовать преобразование данных, бездействия
  • Пробовал установить разделитель строк на (0a), те же результаты

[Источник плоского файла [582]] Внимание: конец файла данных был достигнут во время чтение строк заголовка. Убедитесь, что разделитель строки заголовка и количество строки заголовка для пропусков верны.

Спасибо, что посмотрели на это, и я очень ценю любую помощь, которую вы можете предложить.

4b9b3361

Ответ 1

Причина:

SSIS не может прочитать файл и отображает предупреждение ниже из-за разделителя столбцов Ç ( "c" с cedilla) и not из-за разделитель строк {LF} (подача строки).

[Read flat file [1]] Warning: The end of the data file was reached while 
reading header rows. Make sure the header row delimiter and the number of 
header rows to skip are correct.

Вот пример пакета SSIS, который показывает, как решить проблему с помощью Script Component, а в конце есть еще один пример, который имитирует вашу проблему.

Разрешение:

Ниже образец пакета написан в SSIS 2008 R2. Он читает плоский файл с разделителем строк {LF} как одно значение столбца; затем разбивает данные с помощью Script Component, чтобы вставить информацию в таблицу в базе данных SQL Server 2008 R2.

Используйте Notepad ++, чтобы создать простой плоский файл с несколькими строками. В приведенном ниже образце файл содержит идентификатор продукта и информацию о цене в каждой строке, разделенной символом Ç, в качестве разделителя столбцов, и каждая строка заканчивается разделителем {LF}.

Flat file source

В Notepad ++ нажмите Encoding, а затем нажмите Encoding in UTF-8, чтобы сохранить плоский файл в UTF-8.

Encoding UTF-8

Образец будет использовать базу данных SQL Server 2008 R2 с именем Sora. Создайте новую таблицу с именем dbo.ProductListPrice, используя приведенный ниже script. SSIS вставляет данные плоского файла в эту таблицу.

USE Sora;
GO

CREATE TABLE dbo.ProductListPrice
(
        ProductId   nvarchar(30)    NOT NULL
    ,   ListPrice   numeric(12,2)   NOT NULL
);
GO

Создайте пакет SSIS с помощью Business Intelligence Development Studio (BIDS) 2008 R2. Назовите пакет как SO_6268205.dtsx. Создайте источник данных с именем Sora.ds для подключения к базе данных Sora в SQL Server 2008 R2.

Щелкните правой кнопкой мыши в любом месте пакета, а затем нажмите Variables, чтобы просмотреть панель переменных. Создайте новую переменную с именем ColumnDelimiter типа данных String в области пакета SO_6268205 и установите переменную со значением Ç

Package variables

Щелкните правой кнопкой мыши по Connection Managers и выберите New Flat File Connection..., чтобы создать соединение для чтения плоского файла.

Flat File Connection

На странице General редактора диспетчера подключений плоских файлов выполните следующие действия:

  • Задайте имя менеджера подключений ProductListPrice
  • Установить описание в Flat file connection manager to read product list price information.
  • Выберите путь к файлу. У меня есть файл на пути C:\Siva\StackOverflow\Files\6268205\ProductListPrice.txt
  • Выберите {LF} из разделителя строк заголовка
  • Проверить Column names in the first data row
  • Нажмите Columns страница

Flat File Connection Manager Editor - General

На странице Columns редактора диспетчера подключений плоских файлов убедитесь, что Column delimiter пуст и отключен. Нажмите Advanced.

Flat File Connection Manager Editor - Columns

На странице Advanced редактора диспетчера подключений плоских файлов выполните следующие действия.

  • Задайте имя LineData
  • Убедитесь, что для разделителя столбцов установлено значение {LF}
  • Задайте для DataType значение Unicode string [DT_WSTR]
  • Установите для параметра OutputColumnWidth значение 255
  • Перейдите на страницу Preview.

Flat File Connection Manager Editor - Advanced

На странице Preview редактора диспетчера подключений плоских файлов убедитесь, что отображаемые данные выглядят правильно и нажмите OK.

Flat File Connection Manager Editor - Preview

Вы увидите источник данных Sora и диспетчер соединений с плоскими файлами ProductListPrice на вкладке Connection Managers в нижней части пакета.

Connection Managers

Перетащите Data Flow Task на вкладку "Поток управления" пакета и назовите его как File to database - Without Cedilla delimiter

Data Flow Task 1

Дважды щелкните задачу "Поток данных" , чтобы переключить вид на вкладку Data Flow на упаковке. Перетащите Flat File Source на вкладку "Поток данных" . Дважды щелкните значок "Плоский файл", чтобы открыть Flat File Source Editor.

На странице Connection Manager редактора источника плоского файла выберите Диспетчер соединений с плоскими файлами ProductListPrice и нажмите "Столбцы".

Flat File Source Editor - Connection Manager

На странице Columns редактора исходного файла Flat File проверьте столбец LineData и нажмите OK.

<Т411 >

Перетащите a Script Component на вкладку "Поток данных" ниже "Плоский источник файла", выберите Transformation и нажмите OK. Подключите зеленую стрелку от источника плоского файла к компоненту Script. Дважды щелкните Script Компонент, чтобы открыть Script Transformation Editor.

Нажмите "Входные столбцы" в Script "Редактор трансформации" и выберите столбец LineData. Нажмите "Входы и выходы".

Script Transformation Editor - Input Columns

На странице Inputs and Outputs редактора преобразования Script выполните следующие действия.

  • Измените имя входа на FlatFileInput
  • Измените имя выходов на SplitDataOutput
  • Выберите выходные столбцы и нажмите Add Column. Повторите это еще раз, чтобы добавить еще один столбец.
  • Назовите первый столбец ProductId
  • Задайте DataType для столбца ProductId Unicode string [DT_WSTR]
  • Установите длину в 30

Script Transformation Editor - Inputs and Outputs - ProductId

На странице Inputs and Outputs редактора преобразования Script выполните следующие действия.

  • Назовите второй столбец ListPrice
  • Задайте для DataType столбца ListPrice значение numeric [DT_NUMERIC]
  • Задайте точность 12
  • Установите масштаб 2
  • Нажмите Script страницу, чтобы изменить script

Script Transformation Editor - Inputs and Outputs - ListPrice

На странице Script редактора преобразования Script выполните следующие действия.

  • Нажмите кнопку с многоточием на ReadOnlyVariables и выберите переменную User::ColumnDelimiter
  • Нажмите Edit Script...

Script Transformation Editor - Script

Вставьте ниже С# в редактор Script. Script выполняет следующие задачи.

  • Используя значение разделителя столбца Ç, определенное в переменной User:: ColumnDelimiter, метод FlatFileInput_ProcessInputRow разделяет входящее значение и назначает его двум выходным столбцам, определенным в Script Преобразование компонентов.

Script код компонента в С#

using System;
using System.Data;
using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
using Microsoft.SqlServer.Dts.Runtime.Wrapper;

[Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute]
public class ScriptMain : UserComponent
{
    public override void PreExecute()
    {
        base.PreExecute();
    }

    public override void PostExecute()
    {
        base.PostExecute();
    }

    public override void FlatFileInput_ProcessInputRow(FlatFileInputBuffer Row)
    {
        const int COL_PRODUCT = 0;
        const int COL_PRICE = 1;

        char delimiter = Convert.ToChar(this.Variables.ColumnDelimiter);
        string[] lineData = Row.LineData.ToString().Split(delimiter);

        Row.ProductId = String.IsNullOrEmpty(lineData[COL_PRODUCT]) 
                            ? String.Empty 
                            : lineData[COL_PRODUCT];

        Row.ListPrice = String.IsNullOrEmpty(lineData[COL_PRICE]) 
                            ? 0 
                            : Convert.ToDecimal(lineData[COL_PRICE]);
    }
}

Script Component Code - C#

Перетащите OLE DB Destination на вкладку "Поток данных" . Подключите зеленую стрелку от Script Компонент к назначению OLE DB. Дважды щелкните пункт OLE DB Destination, чтобы открыть OLE DB Destination Editor.

На странице Connection Manager редактора назначения OLE DB выполните следующие действия.

  • Выберите Sora из диспетчера подключений OLE DB
  • Выберите Table or view - fast load из режима доступа к данным
  • Выберите [dbo].[ProductListPrice] из имени таблицы или вида
  • Нажмите "Страницы сопоставлений"

OLE DB Destination Editor - Connection Manager

Нажмите кнопку Mappings в редакторе назначения OLE DB, чтобы автоматически сопоставлять столбцы, если имена столбцов ввода и вывода одинаковы. Нажмите OK.

OLE DB Destination Editor - Mappings

Вкладка "Поток данных" должна выглядеть примерно так после настройки всех компонентов.

Data Flow tab

Выполните запрос select * from dbo.ProductListPrice в SQL Server Management Studio (SSMS), чтобы найти количество строк в таблице. Перед выполнением пакета он должен быть пустым.

Rows in table before package execution

Выполните пакет. Вы заметите, что пакет успешно обработал строки 9. Плоский файл содержит строки 10, но первая строка - это заголовок с именами столбцов.

Package execution without delimiter

Выполните запрос select * from dbo.ProductListPrice в SQL Server Management Studio (SSMS), чтобы найти строки 9, успешно вставленные в таблицу. Данные должны соответствовать плоским данным файла.

Rows in table after package execution

В приведенном выше примере показано, как вручную разделять данные с помощью Script Component, поскольку диспетчер подключений плоских файлов обнаруживает ошибку при настройке разделителя столбцов Ç

Моделирование проблем:

В этом примере показан отдельный диспетчер соединений с плоским файлом, настроенный с разделителем столбцов Ç, который выполняет, но встречает предупреждение и не обрабатывает какие-либо строки.

Щелкните правой кнопкой мыши по Connection Managers и выберите New Flat File Connection..., чтобы создать соединение для чтения плоского файла. На странице General редактора диспетчера подключений плоских файлов выполните следующие действия:

  • Задайте имя менеджера подключений ProductListPrice_Cedilla
  • Установить описание в Flat file connection manager with Cedilla column delimiter.
  • У меня есть файл на пути C:\Siva\StackOverflow\Files\6268205\ProductListPrice.txt Выберите путь к файлу.
  • Выберите {LF} из разделителя строк заголовка
  • Проверить Column names in the first data row
  • Нажмите Columns страница

Flat File Connection Manager Editor - With Cedilla - General

На странице Columns редактора диспетчера подключений плоских файлов выполните следующие действия:

  • Установите разделитель Row на {LF}
  • Поле разделителя столбцов может быть отключено. Нажмите Reset Columns
  • Установите разделитель столбцов на Ç
  • Нажмите Advanced страница

Flat File Connection Manager Editor - With Cedilla - Columns

На странице Advanced редактора диспетчера подключений плоских файлов выполните следующие действия:

  • Задайте имя ProductId
  • Установите для параметра ColumnDelimiter значение Ç
  • Задайте для DataType значение Unicode string [DT_WSTR]
  • Установите длину в 30
  • Нажмите столбец ListPrice

Flat File Connection Manager Editor - With Cedilla - Advanced - ProductId

На странице Advanced редактора диспетчера подключений плоских файлов выполните следующие действия:

  • Задайте имя ListPrice
  • Установите для столбца Delimiter значение {LF}
  • Установите для DataType значение numeric [DT_NUMERIC]
  • Установите DataPrecision на 12
  • Установите DataScale в 2
  • Нажмите OK

Flat File Connection Manager Editor - With Cedilla - Advanced - ListPrice

Перетащите a Data Flow Task на вкладку "Поток управления" и назовите его как File to database - With Cedilla delimiter. Отключите первую задачу потока данных.

Data Flow Task 2

Настройте вторую задачу потока данных с помощью Flat File Source и OLE DB Destination

Data Flow Tab - 2

Дважды щелкните значок "Плоский файл", чтобы открыть Flat File Source Editor. На странице Connection Manager редактора исходного файла Flat File выберите "Диспетчер соединений с плоскими файлами" ProductListPrice_Cedilla и нажмите "Столбцы", чтобы настроить столбцы. Нажмите OK.

Flat File Source Editor - Cedilla

Выполните пакет. Все компоненты будут отображать зеленый цвет, чтобы показать, что процесс был успешным, но никакие строки не будут обработаны. Вы можете видеть, что нет индикаторов номеров строк между Flat File Source и OLE DB Destination

Package Execution - Cedilla

Перейдите на вкладку Progress, и вы увидите следующее предупреждающее сообщение.

[Read flat file [1]] Warning: The end of the data file was reached while 
reading header rows. Make sure the header row delimiter and the number of 
header rows to skip are correct.

Progress Warning message

Ответ 2

Ответ выше кажется ужасно сложным, просто преобразуйте окончания строки в файл

Dim FileContents As String = My.Computer.FileSystem.ReadAllText("c:\Temp\UnixFile.csv")

Dim NewFileContents As String = FileContents.Replace(vbLf, vbCrLf)

My.Computer.FileSystem.WriteAllText("c:\temp\WindowsFile.csv", NewFileContents, False, New System.Text.UnicodeEncoding)

Повторно из здесь

Ответ 3

Эта проблема также возникает, если вы пытаетесь использовать FlatFile, сгенерированный на другой платформе, такой как Unix, Mac и т.д. через SSIS на windows

В таком сценарии все, что вам нужно сделать, - это преобразовать формат файла с сайта UNIX в DOS с помощью команды unix2dos

unix2dos file-to-convert