Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Защо SSIS не разпознава разделителя на ред {LF} за подаване на ред, докато импортира UTF-8 плосък файл?

Причина:

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.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Множество реда до една стойност, разделена със запетая, в Sql Server

  2. Импортиране на Excel в SQL база данни с помощта на vb.net и asp.net

  3. SQL актуализация от една таблица в друга въз основа на съвпадение на идентификатор

  4. SQL Server:изчисляване на периоди от време

  5. Рекурсивен cte sql с ниво на йерархия