Orsak:
SSIS misslyckas med att läsa filen och visar varningen nedan på grund av kolumnavgränsaren Ç
("c" med cedilla ) och not
på grund av radavgränsaren {LF}
(Ladfeed ).
[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.
Här är ett exempel på SSIS-paket som visar hur du löser problemet med Script Component
och i slutet finns ett annat exempel som simulerar ditt problem.
Upplösning:
Nedan exempelpaket är skrivet i SSIS 2008 R2
. Den läser en platt fil med radavgränsare {LF}
som ett enda kolumnvärde; delar sedan upp data med Script Component
för att infoga informationen i en tabell i SQL Server 2008 R2
databas.
Använd Anteckningsblock++
för att skapa en enkel platt fil med få rader. Exempelfilen nedan har Produkt-ID och Listpris information om varje rad åtskilda av Ç
som kolumnavgränsare och varje rad slutar med {LF}
avgränsare.
På Notepad++ klickar du på Encoding
och klicka sedan på Encoding in UTF-8
för att spara den platta filen i UTF-8
kodning.
Exemplet kommer att använda en SQL Server 2008 R2
databas med namnet Sora
. Skapa en ny tabell med namnet dbo.ProductListPrice
med hjälp av nedanstående skript. SSIS kommer att infoga platt fildata i denna tabell.
USE Sora;
GO
CREATE TABLE dbo.ProductListPrice
(
ProductId nvarchar(30) NOT NULL
, ListPrice numeric(12,2) NOT NULL
);
GO
Skapa ett SSIS-paket med Business Intelligence Development Studio (BIDS) 2008 R2 . Namnge paketet som SO_6268205.dtsx
. Skapa en datakälla med namnet Sora.ds
för att ansluta till databasen Sora
i SQL Server 2008 R2 .
Högerklicka var som helst i paketet och klicka sedan på Variables
för att visa variabelfönstret. Skapa en ny variabel med namnet ColumnDelimiter
av datatypen String
i paketets omfattning SO_6268205
och ställ in variabeln med värdet Ç
Högerklicka på Connection Managers
och klicka på New Flat File Connection...
för att skapa en anslutning för att läsa den platta filen.
På General
sidan i Flat File Connection Manager Editor , utför följande åtgärder:
- Ange Anslutningshanterarens namn till
ProductListPrice
- Ange Beskrivning till
Flat file connection manager to read product list price information.
- Välj den platta filsökvägen. Jag har filen i sökvägen
C:\Siva\StackOverflow\Files\6268205\ProductListPrice.txt
- Välj
{LF}
från Rubrikradavgränsare - Kontrollera
Column names in the first data row
- Klicka på
Columns
sida
På Columns
sidan i Flat File Connection Manager Editor , kontrollera att Column delimiter
är tom och inaktiverad. Klicka på Advanced
sida.
På Advanced
sidan i Flat File Connection Manager Editor , utför följande åtgärder.
- Ange namn till
LineData
- Verifiera att kolumnavgränsaren är inställd på
{LF}
- Ställ in DataTyp till
Unicode string [DT_WSTR]
- Ställ in OutputColumnWidth till
255
- Klicka på
Preview
sida.
På Preview
sidan i Flat File Connection Manager Editor , kontrollera att de visade uppgifterna ser korrekta ut och klicka på OK
.
Du kommer att se datakällan Sora och den platta filanslutningshanteraren ProductListPrice på Connection Managers
fliken längst ner på paketet.
Dra och släpp Data Flow Task
till Kontrollflöde fliken i paketet och namnge det som File to database - Without Cedilla delimiter
Dubbelklicka på Dataflödesuppgiften för att byta vyn till Data Flow
fliken på paketet. Dra och släpp en Flat File Source
på Dataflöde flik. Dubbelklicka på Flat filkälla för att öppna Flat File Source Editor
.
På Connection Manager
sidan i Flat File Source Editor , välj Anslutningshanteraren för platt fil ProductListPrice
och klicka på Kolumner sida.
På Columns
sidan i Flat File Source Editor , kontrollera kolumnen LineData
och klicka på OK
.
Dra och släpp en Script Component
till Dataflödet fliken under Flat filkälla , välj Transformation
och klicka på OK
. Anslut den gröna pilen från Flat filkälla till Skriptkomponent . Dubbelklicka på Skriptkomponent för att öppna Script Transformation Editor
.
Klicka på Inmatningskolumner på Script Transformation Editor och välj LineData
kolumn. Klicka på Ingångar och utgångar sida.
På Inputs and Outputs
sida i Script Transformation Editor , utför följande åtgärder.
- Ändra ingångarnas namn till FlatFileInput
- Ändra utdatanamnet till
SplitDataOutput
- Välj Utdatakolumner och klicka på
Add Column
. Upprepa detta igen för att lägga till ytterligare en kolumn. - Ge den första kolumnen ett namn
ProductId
- Ställ in DataTyp i kolumnen ProductId till
Unicode string [DT_WSTR]
- Ställ in Längd till
30
På Inputs and Outputs
sida i Script Transformation Editor , utför följande åtgärder.
- Ge den andra kolumnen ett namn
ListPrice
- Ställ in DataTyp i kolumnen ListPrice till
numeric [DT_NUMERIC]
- Ställ in Precision till
12
- Ställ in skalan till
2
- Klicka på Script sida för att ändra skriptet
På Script
sida i Script Transformation Editor , utför följande åtgärder.
- Klicka på ellipsknappen mot ReadOnlyVariables och välj variabeln
User::ColumnDelimiter
- Klicka på
Edit Script...
Klistra in nedanstående C# i Script Editor. Skriptet utför följande uppgifter.
- Använda kolumnavgränsningsvärdet
Ç
definieras i variabeln User::ColumnDelimiter , metodenFlatFileInput_ProcessInputRow
delar det inkommande värdet och tilldelar det till de två utdatakolumnerna som definieras i skriptkomponenttransformationen.
Skriptkomponentkod i 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]);
}
}
Dra och släpp OLE DB Destination
till Dataflödet flik. Anslut den gröna pilen från Skriptkomponent till OLE DB-destination . Dubbelklicka på OLE DB-destination för att öppna OLE DB Destination Editor
.
På Connection Manager
sida i OLE DB Destination Editor , utför följande åtgärder.
- Välj
Sora
från OLE DB Connection Manager - Välj
Table or view - fast load
från Dataåtkomstläge - Välj
[dbo].[ProductListPrice]
från Namn på tabellen eller vyn - Klicka på Mappningar sida
Klicka på Mappings
sidan på OLE DB Destination Editor skulle automatiskt mappa kolumnerna om ingångs- och utdatakolumnnamnen är samma. Klicka på OK
.
Dataflöde fliken bör se ut ungefär så här efter att ha konfigurerat alla komponenter.
Kör frågan select * from dbo.ProductListPrice
i SQL Server Management Studio (SSMS) för att hitta antalet rader i tabellen. Det bör vara tomt innan paketet körs.
Kör paketet. Du kommer att märka att paketet har bearbetats 9 rader. Den platta filen innehåller 10 rader men den första raden är rubrik med kolumnnamn.
Kör frågan select * from dbo.ProductListPrice
i SQL Server Management Studio (SSMS) för att hitta 9 rader har infogats i tabellen. Data bör matcha med platt fildata.
Exemplet ovan illustrerade hur man manuellt delar upp data med Script Component eftersom Flat File Connection Manager stöter på fel när kolumnavgränsaren Ç
konfigureras
Problemsimulering:
Det här exemplet visar en separat Flat File Connection Manager konfigurerad med kolumnavgränsare Ç
, som körs men stöter på en varning och inte bearbetar några rader.
Högerklicka på Connection Managers
och klicka på New Flat File Connection...
för att skapa en anslutning för att läsa den platta filen. På General
sidan i Flat File Connection Manager Editor , utför följande åtgärder:
- Ange Anslutningshanterarens namn till
ProductListPrice_Cedilla
- Sätt Beskrivning på
Flat file connection manager with Cedilla column delimiter.
- Jag har filen i sökvägen
C:\Siva\StackOverflow\Files\6268205\ProductListPrice.txt
Välj den platta filsökvägen. - Välj
{LF}
från Rubrikradavgränsare - Kontrollera
Column names in the first data row
- Klicka på
Columns
sida
På Columns
sidan i Flat File Connection Manager Editor , utför följande åtgärder:
- Ställ in radavgränsare till
{LF}
- Fältet för kolumnavgränsare kan vara inaktiverat. Klicka på
Reset Columns
- Ange kolumnavgränsare till
Ç
- Klicka på
Advanced
sida
På Advanced
sidan i Flat File Connection Manager Editor , utför följande åtgärder:
- Ange namn till
ProductId
- Ställ in ColumnDelimiter till
Ç
- Ställ in DataTyp till
Unicode string [DT_WSTR]
- Ställ in Längd till
30
- Klicka på kolumnen
ListPrice
På Advanced
sidan i Flat File Connection Manager Editor , utför följande åtgärder:
- Ange namn till
ListPrice
- Ställ in ColumnDelimiter till
{LF}
- Ställ in DataTyp till
numeric [DT_NUMERIC]
- Ställ in Dataprecision till
12
- Ställ in DataScale till
2
- Klicka på
OK
Dra och släpp en Data Flow Task
till Kontrollflöde flik och namnge den som File to database - With Cedilla delimiter
. Inaktivera den första dataflödesuppgiften.
Konfigurera den andra dataflödesuppgiften med Flat File Source
och OLE DB Destination
Dubbelklicka på Flat File Source för att öppna Flat File Source Editor
. På Connection Manager
sidan i Flat File Source Editor , välj Anslutningshanteraren för platt fil ProductListPrice_Cedilla
och klicka på Kolumner sida för att konfigurera kolumnerna. Klicka på OK
.
Kör paketet. Alla komponenter kommer att visa grön färg för att indikera att processen lyckades men inga rader kommer att bearbetas. Du kan se att det inte finns några radnummer mellan Flat File Source
och OLE DB Destination
Klicka på Progress
fliken och du kommer att märka följande varningsmeddelande.
[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.