Причина:
SSIS не успява да прочете файла и показва предупреждението по-долу поради разделителя на колони Ç
("c" със седила ) и 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++
за създаване на прост плосък файл с няколко реда. Примерният файл по-долу има ID на продукта и Каталожна цена информация за всеки ред, разделени с Ç
като разделител на колони и всеки ред завършва с {LF}
разделител.
В Notepad++ щракнете върху Encoding
и след това щракнете върху Encoding in UTF-8
за да запишете плоския файл в UTF-8
кодиране.
Примерът ще използва SQL Server 2008 R2
база данни с име Sora
. Създайте нова таблица с име dbo.ProductListPrice
използвайки дадения по-долу скрипт. 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
страница на редактора на изходния код на плосък файл проверете колоната LineData
и щракнете върху OK
.
Плъзнете и пуснете Script Component
към потока от данни под Източник на плосък файл , изберете Transformation
и щракнете върху OK
. Свържете зелената стрелка от Източник на плосък файл към компонент на скрипт . Щракнете двукратно върху компонент на скрипт за да отворите Script Transformation Editor
.
Кликнете върху Колони за въвеждане в Редактор на трансформация на скрипт и изберете LineData
колона. Щракнете върху Входове и изходи страница.
На Inputs and Outputs
страница на Редактора за преобразуване на скрипт , изпълнете следните действия.
- Променете името на входовете на FlatFileInput
- Променете името на изходите на
SplitDataOutput
- Изберете Изходни колони и щракнете върху
Add Column
. Повторете това отново, за да добавите друга колона. - Именувайте първата колона
ProductId
- Задайте DataType на колона ProductId към
Unicode string [DT_WSTR]
- Задайте дължина до
30
На Inputs and Outputs
страница на Редактора за преобразуване на скрипт , изпълнете следните действия.
- Именувайте втората колона
ListPrice
- Задайте DataType от колона ListPrice към
numeric [DT_NUMERIC]
- Задайте Прецизност до
12
- Задайте мащаба към
2
- Щракнете върху Скрипт страница за модифициране на скрипта
На Script
страница на Редактора за преобразуване на скрипт , изпълнете следните действия.
- Щракнете върху бутона с многоточие срещу ReadOnlyVariables и изберете променливата
User::ColumnDelimiter
- Щракнете върху
Edit Script...
Поставете C# по-долу в редактора на скриптове. Скриптът изпълнява следните задачи.
- Използване на стойността на разделителя на колони
Ç
дефинирани в променливата User::ColumnDelimiter , методътFlatFileInput_ProcessInputRow
разделя входящата стойност и я присвоява на двете изходни колони, дефинирани в трансформацията на компонента на скрипта.
Код на компонент на скрипт в C#
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 Component към OLE DB дестинация . Щракнете двукратно върху OLE DB дестинация за да отворите OLE DB Destination Editor
.
В Connection Manager
страница на OLE DB дестинационен редактор , изпълнете следните действия.
- Изберете
Sora
от OLE DB Connection Manager - Изберете
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
страница на редактора на диспечера на връзките с плоски файлове , изпълнете следните действия:
- Задаване на разделител на ред до
{LF}
- Полето за разделител на колони може да е деактивирано. Щракнете върху
Reset Columns
- Задаване на разделител на колони до
Ç
- Щракнете върху
Advanced
страница
В Advanced
страница на редактора на диспечера на връзките с плоски файлове , изпълнете следните действия:
- Задайте име към
ProductId
- Задайте ColumnDelimiter до
Ç
- Задайте DataType към
Unicode string [DT_WSTR]
- Задайте дължина до
30
- Щракнете върху колона
ListPrice
В Advanced
страница на редактора на диспечера на връзките с плоски файлове , изпълнете следните действия:
- Задайте име към
ListPrice
- Задайте ColumnDelimiter до
{LF}
- Задайте DataType към
numeric [DT_NUMERIC]
- Задайте DataPrecision до
12
- Задайте DataScale към
2
- Щракнете върху
OK
Плъзнете и пуснете Data Flow task
към контролния поток и го наименувайте като File to database - With Cedilla delimiter
. Деактивирайте първата задача за поток от данни.
Конфигурирайте втората задача за поток от данни с Flat File Source
и OLE DB Destination
Щракнете двукратно върху източника на плосък файл, за да отворите Flat File Source Editor
. В Connection Manager
страница на редактора на изходния код на плосък файл , изберете Диспечер на връзки с плоски файлове 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.