Ответ 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}
.
В Notepad ++ нажмите Encoding
, а затем нажмите Encoding in UTF-8
, чтобы сохранить плоский файл в 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
и установите переменную со значением Ç
Щелкните правой кнопкой мыши по Connection Managers
и выберите New 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
страница
На странице Columns
редактора диспетчера подключений плоских файлов убедитесь, что Column delimiter
пуст и отключен. Нажмите Advanced
.
На странице Advanced
редактора диспетчера подключений плоских файлов выполните следующие действия.
- Задайте имя
LineData
- Убедитесь, что для разделителя столбцов установлено значение
{LF}
- Задайте для DataType значение
Unicode string [DT_WSTR]
- Установите для параметра OutputColumnWidth значение
255
- Перейдите на страницу
Preview
.
На странице Preview
редактора диспетчера подключений плоских файлов убедитесь, что отображаемые данные выглядят правильно и нажмите OK
.
Вы увидите источник данных Sora и диспетчер соединений с плоскими файлами ProductListPrice на вкладке Connection Managers
в нижней части пакета.
Перетащите Data Flow Task
на вкладку "Поток управления" пакета и назовите его как File to database - Without Cedilla delimiter
Дважды щелкните задачу "Поток данных" , чтобы переключить вид на вкладку Data Flow
на упаковке. Перетащите Flat File Source
на вкладку "Поток данных" . Дважды щелкните значок "Плоский файл", чтобы открыть Flat File Source Editor
.
На странице Connection Manager
редактора источника плоского файла выберите Диспетчер соединений с плоскими файлами ProductListPrice
и нажмите "Столбцы".
На странице Columns
редактора исходного файла Flat File проверьте столбец LineData
и нажмите OK
.
<Т411 >
Перетащите a Script Component
на вкладку "Поток данных" ниже "Плоский источник файла", выберите Transformation
и нажмите OK
. Подключите зеленую стрелку от источника плоского файла к компоненту Script. Дважды щелкните Script Компонент, чтобы открыть Script Transformation Editor
.
Нажмите "Входные столбцы" в Script "Редактор трансформации" и выберите столбец LineData
. Нажмите "Входы и выходы".
На странице Inputs and Outputs
редактора преобразования Script выполните следующие действия.
- Измените имя входа на FlatFileInput
- Измените имя выходов на
SplitDataOutput
- Выберите выходные столбцы и нажмите
Add Column
. Повторите это еще раз, чтобы добавить еще один столбец. - Назовите первый столбец
ProductId
- Задайте DataType для столбца ProductId
Unicode string [DT_WSTR]
- Установите длину в
30
На странице Inputs and Outputs
редактора преобразования Script выполните следующие действия.
- Назовите второй столбец
ListPrice
- Задайте для DataType столбца ListPrice значение
numeric [DT_NUMERIC]
- Задайте точность
12
- Установите масштаб
2
- Нажмите Script страницу, чтобы изменить script
На странице Script
редактора преобразования Script выполните следующие действия.
- Нажмите кнопку с многоточием на ReadOnlyVariables и выберите переменную
User::ColumnDelimiter
- Нажмите
Edit 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]);
}
}
Перетащите 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]
из имени таблицы или вида - Нажмите "Страницы сопоставлений"
Нажмите кнопку Mappings
в редакторе назначения OLE DB, чтобы автоматически сопоставлять столбцы, если имена столбцов ввода и вывода одинаковы. Нажмите OK
.
Вкладка "Поток данных" должна выглядеть примерно так после настройки всех компонентов.
Выполните запрос select * from dbo.ProductListPrice
в SQL Server Management Studio (SSMS), чтобы найти количество строк в таблице. Перед выполнением пакета он должен быть пустым.
Выполните пакет. Вы заметите, что пакет успешно обработал строки 9. Плоский файл содержит строки 10, но первая строка - это заголовок с именами столбцов.
Выполните запрос select * from dbo.ProductListPrice
в SQL Server Management Studio (SSMS), чтобы найти строки 9, успешно вставленные в таблицу. Данные должны соответствовать плоским данным файла.
В приведенном выше примере показано, как вручную разделять данные с помощью 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
страница
На странице Columns
редактора диспетчера подключений плоских файлов выполните следующие действия:
- Установите разделитель Row на
{LF}
- Поле разделителя столбцов может быть отключено. Нажмите
Reset Columns
- Установите разделитель столбцов на
Ç
- Нажмите
Advanced
страница
На странице Advanced
редактора диспетчера подключений плоских файлов выполните следующие действия:
- Задайте имя
ProductId
- Установите для параметра ColumnDelimiter значение
Ç
- Задайте для DataType значение
Unicode string [DT_WSTR]
- Установите длину в
30
- Нажмите столбец
ListPrice
На странице Advanced
редактора диспетчера подключений плоских файлов выполните следующие действия:
- Задайте имя
ListPrice
- Установите для столбца Delimiter значение
{LF}
- Установите для DataType значение
numeric [DT_NUMERIC]
- Установите DataPrecision на
12
- Установите DataScale в
2
- Нажмите
OK
Перетащите a Data Flow Task
на вкладку "Поток управления" и назовите его как File to database - With Cedilla delimiter
. Отключите первую задачу потока данных.
Настройте вторую задачу потока данных с помощью Flat File Source
и OLE DB Destination
Дважды щелкните значок "Плоский файл", чтобы открыть Flat File Source Editor
. На странице Connection Manager
редактора исходного файла Flat File выберите "Диспетчер соединений с плоскими файлами" ProductListPrice_Cedilla
и нажмите "Столбцы", чтобы настроить столбцы. Нажмите OK
.
Выполните пакет. Все компоненты будут отображать зеленый цвет, чтобы показать, что процесс был успешным, но никакие строки не будут обработаны. Вы можете видеть, что нет индикаторов номеров строк между Flat File Source
и OLE DB Destination
Перейдите на вкладку 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.