web-dev-qa-db-fra.com

Pourquoi SSIS ne reconnaît-il pas le délimiteur de ligne de saut de ligne {LF} lors de l'importation d'un fichier plat UTF-8?

J'essaie d'importer des données d'un fichier plat encodé en utf-8 dans SQL Server 2008 à l'aide de SSIS. Voici à quoi ressemble la fin des données de ligne dans Notepad ++:

enter image description here

J'ai quelques images supplémentaires montrant à quoi ressemble le gestionnaire de connexion de fichiers:

enter image description here

enter image description here

Vous pouvez voir que les données s'affichent correctement dans l'aperçu du gestionnaire de connexions de fichiers. Lorsque j'essaie d'importer ces données, aucune ligne n'est importée. J'obtiens un message d'erreur indiquant que le délimiteur de ligne est introuvable. Vous pouvez voir dans les images du gestionnaire de connexions de fichiers que le délimiteur de ligne d'en-tête et le délimiteur de ligne sont tous deux définis sur {LF}. C'était suffisant pour générer l'aperçu correct, donc je ne comprends pas pourquoi cela n'a pas fonctionné pour importer. J'ai essayé un certain nombre de choses qui n'ont donné aucun résultat:

  • Essayé en utilisant Wizard importation dans SSMS ... mêmes résultats
  • Testé à l'aide de la conversion de données, aucun impact
  • J'ai essayé de définir le délimiteur de ligne sur (0a), mêmes résultats

[Source de fichier plat [582]] Avertissement: la fin du fichier de données a été atteinte lors de la lecture des lignes d'en-tête. Assurez-vous que le délimiteur de lignes d'en-tête et le nombre de lignes d'en-tête à ignorer sont corrects.

Merci d'avoir regardé cela et j'apprécie vraiment toute aide que vous pouvez offrir.

29
K Richard

Cause:

SSIS ne parvient pas à lire le fichier et affiche l'avertissement ci-dessous en raison du délimiteur de colonne Ç ( "c" avec cédille) et not en raison du délimiteur de ligne {LF} ( Saut de ligne).

[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.

Voici un exemple de package SSIS qui montre comment résoudre le problème à l'aide de Script Component et à la fin il y a un autre exemple qui simule votre problème.

Résolution:

L'échantillon ci-dessous est écrit en SSIS 2008 R2. Il lit un fichier plat avec un délimiteur de ligne {LF} en tant que valeur de colonne unique; divise ensuite les données à l'aide de Script Component pour insérer les informations dans un tableau dans SQL Server 2008 R2 base de données.

Utilisez Notepad ++ pour créer un fichier plat simple avec quelques lignes. L'exemple de fichier ci-dessous contient ID produit et Prix catalogue des informations sur chaque ligne séparées par Ç comme délimiteur de colonne et chaque ligne se termine par {LF} délimiteur.

Flat file source

Sur le Bloc-notes ++, cliquez sur Encoding puis cliquez sur Encoding in UTF-8 pour enregistrer le fichier plat dans UTF-8 encodage.

Encoding UTF-8

L'échantillon utilisera un SQL Server 2008 R2 base de données nommée Sora. Créez une nouvelle table nommée dbo.ProductListPrice en utilisant le script ci-dessous. SSIS insérera les données du fichier plat dans ce tableau.

USE Sora;
GO

CREATE TABLE dbo.ProductListPrice
(
        ProductId   nvarchar(30)    NOT NULL
    ,   ListPrice   numeric(12,2)   NOT NULL
);
GO

Créez un package SSIS à l'aide de Business Intelligence Development Studio (BIDS) 2008 R2. Nommez le package comme SO_6268205.dtsx. Créez une source de données nommée Sora.ds pour se connecter à la base de données Sora dans SQL Server 2008 R2.

Cliquez avec le bouton droit n'importe où dans le package, puis cliquez sur Variables pour afficher le volet des variables. Créez une nouvelle variable nommée ColumnDelimiter de type de données String dans la portée du package SO_6268205 et définissez la variable avec la valeur Ç

Package variables

Faites un clic droit sur le Connection Managers et cliquez sur New Flat File Connection... pour créer une connexion pour lire le fichier plat.

Flat File Connection

Sur la page General de l'éditeur Flat File Connection Manager, effectuez les actions suivantes:

  • Définissez Nom du gestionnaire de connexions sur ProductListPrice
  • Définissez Description sur Flat file connection manager to read product list price information.
  • Sélectionnez le chemin du fichier plat. J'ai le fichier dans le chemin C:\Siva\StackOverflow\Files\6268205\ProductListPrice.txt
  • Sélectionnez {LF} de Délimiteur de ligne d'en-tête
  • Vérifiez Column names in the first data row
  • Cliquez sur Columns page

Flat File Connection Manager Editor - General

Sur la page Columns de l'éditeur Flat File Connection Manager, vérifiez que le Column delimiter est vide et désactivé. Cliquez sur Advanced page.

Flat File Connection Manager Editor - Columns

Sur la page Advanced de l'éditeur Flat File Connection Manager, effectuez les actions suivantes.

  • Définissez Nom sur LineData
  • Vérifiez que Délimiteur de colonne est défini sur {LF}
  • Définissez le DataType sur Unicode string [DT_WSTR]
  • Définissez OutputColumnWidth sur 255
  • Cliquez sur la page Preview.

Flat File Connection Manager Editor - Advanced

Sur la page Preview de l'éditeur Flat File Connection Manager, vérifiez que les données affichées sont correctes et cliquez sur OK.

Flat File Connection Manager Editor - Preview

Vous verrez la source de données Sora et le gestionnaire de connexion de fichiers plats ProductListPrice sur le Connection Managers onglet en bas de l'emballage.

Connection Managers

Glisser déposer Data Flow Task sur l'onglet Control Flow du package et nommez-le File to database - Without Cedilla delimiter

Data Flow Task 1

Double-cliquez sur Tâche de flux de données pour basculer la vue sur Data Flow onglet sur le paquet. Faites glisser et déposez un Flat File Source dans l'onglet Flux de données. Double-cliquez sur Flat File Source pour ouvrir Flat File Source Editor.

Sur le Connection Manager page de Flat File Source Editor, sélectionnez Flat File Connection ManagerProductListPrice et cliquez Colonnes page.

Flat File Source Editor - Connection Manager

Sur la page Columns de l'éditeur Flat File Source Editor, vérifiez la colonne LineData et cliquez sur OK.

Flat File Source Editor - Columns

Faites glisser et déposez un Script Component sur l'onglet Flux de données sous le Source du fichier plat, sélectionnez Transformation et cliquez sur OK. Connectez la flèche verte de Source de fichier plat à Composant de script. Double-cliquez sur Composant de script pour ouvrir Script Transformation Editor.

Cliquez sur Colonnes d'entrée sur Éditeur de transformation de script et sélectionnez la colonne LineData. Cliquez sur Entrées et sorties page.

Script Transformation Editor - Input Columns

Sur le Inputs and Outputs page de Script Transformation Editor, effectuez les actions suivantes.

  • Remplacez le nom des entrées par FlatFileInput
  • Remplacez le nom des sorties par SplitDataOutput
  • Sélectionnez Colonnes de sortie et cliquez sur Add Column. Répétez cette opération pour ajouter une autre colonne.
  • Nommez la première colonne ProductId
  • Définissez le DataType de la colonne ProductId à Unicode string [DT_WSTR]
  • Définissez Longueur à 30

Script Transformation Editor - Inputs and Outputs - ProductId

Sur le Inputs and Outputs page de l'éditeur Script Transformation Editor, effectuez les actions suivantes.

  • Nommez la deuxième colonne ListPrice
  • Définissez le DataType de la colonne ListPrice à numeric [DT_NUMERIC]
  • Définissez Précision à 12
  • Réglez le Scale sur 2
  • Cliquez sur Script page pour modifier le script

Script Transformation Editor - Inputs and Outputs - ListPrice

Sur la page Script de Éditeur de transformation de script, effectuez les actions suivantes.

  • Cliquez sur le bouton Points de suspension contre ReadOnlyVariables et sélectionnez la variable User::ColumnDelimiter
  • Cliquez sur Edit Script...

Script Transformation Editor - Script

Collez le C # ci-dessous dans l'éditeur de script. Le script effectue les tâches suivantes.

  • Utilisation de la valeur du délimiteur de colonne Ç défini dans la variable User :: ColumnDelimiter, la méthode FlatFileInput_ProcessInputRow divise la valeur entrante et l'affecte aux deux colonnes de sortie définies dans la transformation Composant de script.

Code de composant de script en 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]);
    }
}

Script Component Code - C#

Faites glisser et déposez OLE DB Destination dans l'onglet Flux de données. Connectez la flèche verte de Composant de script à Destination OLE DB. Double-cliquez sur Destination OLE DB pour ouvrir OLE DB Destination Editor.

Sur le Connection Manager page de Éditeur de destination OLE DB, effectuez les actions suivantes.

  • Sélectionnez Sora dans OLE DB Connection Manager
  • Sélectionnez Table or view - fast load de Mode d'accès aux données
  • Sélectionnez [dbo].[ProductListPrice] de Nom de la table ou de la vue
  • Cliquez sur Mappages page

OLE DB Destination Editor - Connection Manager

Cliquez sur la page Mappings dans Éditeur de destination OLE DB mapperait automatiquement les colonnes si les noms des colonnes d'entrée et de sortie sont identiques. Cliquez sur OK.

OLE DB Destination Editor - Mappings

Data Flow tab devrait ressembler à ceci après avoir configuré tous les composants.

Data Flow tab

Exécutez la requête select * from dbo.ProductListPrice dans le SQL Server Management Studio (SSMS) pour trouver le nombre de lignes dans le tableau. Il doit être vide avant d'exécuter le package.

Rows in table before package execution

Exécutez le package. Vous remarquerez que le package a correctement traité 9 lignes. Le fichier plat contient 10 lignes mais la première ligne est un en-tête avec des noms de colonne.

Package execution without delimiter

Exécutez la requête select * from dbo.ProductListPrice dans le SQL Server Management Studio (SSMS) pour trouver les 9 lignes correctement insérées dans la table. Les données doivent correspondre aux données de fichier plat.

Rows in table after package execution

L'exemple ci-dessus montre comment fractionner manuellement les données à l'aide de Composant de script car l'erreur Gestionnaire de connexion de fichiers plats rencontre l'erreur lors de la configuration du délimiteur de colonne Ç

Simulation de problème:

Cet exemple montre un Flat File Connection Manager séparé configuré avec un délimiteur de colonne Ç, qui s'exécute mais rencontre un avertissement et ne traite aucune ligne.

Faites un clic droit sur le Connection Managers et cliquez sur New Flat File Connection... pour créer une connexion pour lire le fichier plat. Sur la page General de l'éditeur Flat File Connection Manager, effectuez les actions suivantes:

  • Définissez Nom du gestionnaire de connexions à ProductListPrice_Cedilla
  • Définissez la description sur Flat file connection manager with Cedilla column delimiter.
  • J'ai le fichier dans le chemin C:\Siva\StackOverflow\Files\6268205\ProductListPrice.txt Sélectionnez le chemin du fichier plat.
  • Sélectionnez {LF} de Délimiteur de ligne d'en-tête
  • Vérifiez Column names in the first data row
  • Cliquez sur Columns page

Flat File Connection Manager Editor - With Cedilla - General

Sur la page Columns de l'éditeur Flat File Connection Manager, effectuez les actions suivantes:

  • Définissez Délimiteur de lignes à {LF}
  • Le champ délimiteur de colonne peut être désactivé. Cliquez sur Reset Columns
  • Définissez Délimiteur de colonne à Ç
  • Cliquez sur Advanced page

Flat File Connection Manager Editor - With Cedilla - Columns

Sur la page Advanced de l'éditeur Flat File Connection Manager, effectuez les actions suivantes:

  • Définissez Nom sur ProductId
  • Définissez le ColumnDelimiter sur Ç
  • Définissez le DataType sur Unicode string [DT_WSTR]
  • Définissez Longueur à 30
  • Cliquez sur la colonne ListPrice

Flat File Connection Manager Editor - With Cedilla - Advanced - ProductId

Sur la page Advanced de l'éditeur Flat File Connection Manager, effectuez les actions suivantes:

  • Définissez Nom sur ListPrice
  • Définissez le ColumnDelimiter sur {LF}
  • Définissez le DataType sur numeric [DT_NUMERIC]
  • Définissez DataPrecision à 12
  • Définissez DataScale sur 2
  • Cliquez sur OK

Flat File Connection Manager Editor - With Cedilla - Advanced - ListPrice

Faites glisser et déposez un Data Flow task sur l'onglet Control Flow et nommez-le comme File to database - With Cedilla delimiter. Désactivez la première tâche de flux de données.

Data Flow Task 2

Configurez la deuxième tâche de flux de données avec Flat File Source et OLE DB Destination

Data Flow Tab - 2

Double-cliquez sur la source du fichier plat pour ouvrir Flat File Source Editor. Sur le Connection Manager page de l'éditeur Flat File Source Editor, sélectionnez Flat File Connection ManagerProductListPrice_Cedilla et cliquez sur Colonnes page pour configurer les colonnes. Cliquez sur OK.

Flat File Source Editor - Cedilla

Exécutez le package. Tous les composants afficheront une couleur verte pour indiquer que le processus a réussi, mais aucune ligne ne sera traitée. Vous pouvez voir qu'il n'y a pas d'indication de numéros de lignes entre les Flat File Source et OLE DB Destination

Package Execution - Cedilla

Cliquez sur l'onglet Progress et vous remarquerez le message d'avertissement suivant.

[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.

Progress Warning message

62
user756519

La réponse ci-dessus semble terriblement compliquée, il suffit de convertir les fins de ligne dans le fichier

Dim FileContents As String = My.Computer.FileSystem.ReadAllText("c:\Temp\UnixFile.csv")

Dim NewFileContents As String = FileContents.Replace(vbLf, vbCrLf)

My.Computer.FileSystem.WriteAllText("c:\temp\WindowsFile.csv", NewFileContents, False, New System.Text.UnicodeEncoding)

Rehashed from here

1
Richard

Ce problème se pose également si vous essayez de consommer FlatFile généré sur une plate-forme différente comme Unix, Mac, etc. via SSIS sur Windows

Dans un tel scénario, tout ce que vous devez faire est de convertir le format de fichier de disons UNIX en DOS avec la commande unix2dos

unix2dos file-to-convert
0
Jeevan