sql >> Databasteknik >  >> RDS >> Sqlserver

Varför känner inte SSIS igen radavgränsare för radmatning {LF} vid import av platt UTF-8-fil?

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.

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

Columns sidan i Flat File Connection Manager Editor , kontrollera att Column delimiter är tom och inaktiverad. Klicka på Advanced sida.

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.

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 ProductListPriceConnection 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 Dataflöde flik. Dubbelklicka på Flat filkälla för att öppna Flat File Source Editor .

Connection Manager sidan i Flat File Source Editor , välj Anslutningshanteraren för platt fil ProductListPrice och klicka på Kolumner sida.

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å InmatningskolumnerScript Transformation Editor och välj LineData kolumn. Klicka på Ingångar och utgångar sida.

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

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

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 , metoden FlatFileInput_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 .

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

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

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

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.



  1. infoga data med mysql Connector i python

  2. En introduktion till TimescaleDB

  3. Varför skapas alla mina tabeller i Rails 4/Postgres med dimensionen 1?

  4. Vilken är standardtransaktionsisoleringsnivån för SQL Server med ADO.NET?