Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

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

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'exemple de package 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 ; puis divise les données en utilisant Script Component pour insérer les informations dans une table 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 un identifiant de produit et Prix catalogue informations sur chaque ligne séparées par Ç comme délimiteur de colonne et chaque ligne se termine par {LF} délimiteur.

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

L'exemple 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 cette table.

USE Sora;
GO

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

Créer 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 se connecter à la base de données Sora dans SQL Server 2008 R2 .

Faites un clic 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 Ç

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

Sur le General page de l'Éditeur du gestionnaire de connexions de fichiers plats , effectuez les actions suivantes :

  • Définir le nom du gestionnaire de connexion à ProductListPrice
  • Définir la description au 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 pages

Sur les Columns page de l'Éditeur du gestionnaire de connexions de fichiers plats , vérifiez que le Column delimiter est vide et désactivé. Cliquez sur Advanced page.

Sur Advanced page de l'Éditeur du gestionnaire de connexions de fichiers plats , effectuez les actions suivantes.

  • Définir le Nom à LineData
  • Vérifiez que le délimiteur de colonne est défini sur {LF}
  • Définir le Type de données en Unicode string [DT_WSTR]
  • Définir la OutputColumnWidth à 255
  • Cliquez sur Preview page.

Sur l'Preview page de l'Éditeur du gestionnaire de connexions de fichiers plats , vérifiez que les données affichées semblent correctes et cliquez sur OK .

Vous verrez la source de données Sora et le gestionnaire de connexion de fichier plat ProductListPrice sur les Connection Managers onglet au bas du paquet.

Faites glisser et déposez Data Flow Task sur le flux de contrôle du package et nommez-le File to database - Without Cedilla delimiter

Double-cliquez sur la tâche de flux de données pour basculer la vue vers le Data Flow onglet sur le paquet. Faites glisser et déposez une Flat File Source sur le flux de données languette. Double-cliquez sur la source de fichier plat pour ouvrir Flat File Source Editor .

Sur le Connection Manager page de l'Éditeur de source de fichier plat , sélectionnez le Gestionnaire de connexions de fichiers plats ProductListPrice et cliquez sur Colonnes page.

Sur les Columns page de l'Éditeur de source de fichier plat , vérifiez la colonne LineData et cliquez sur OK .

Faites glisser et déposez un Script Component sur le flux de données onglet sous la source de fichier plat , sélectionnez Transformation et cliquez sur OK . Connectez la flèche verte de Flat File Source au 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 LineData colonne. Cliquez sur Entrées et sorties page.

Sur les Inputs and Outputs page de l'Éditeur de transformation de script , effectuez les actions suivantes.

  • Changer le nom des entrées en FlatFileInput
  • Changer le nom des sorties en 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éfinir le Type de données de la colonne ProductId en Unicode string [DT_WSTR]
  • Définissez la longueur à 30

Sur les Inputs and Outputs page de l'Éditeur de transformation de script , effectuez les actions suivantes.

  • Nommez la deuxième colonne ListPrice
  • Définir le Type de données de la colonne ListPrice en numeric [DT_NUMERIC]
  • Définir la précision à 12
  • Définir l'échelle à 2
  • Cliquez sur Script page pour modifier le script

Sur le Script page de l'É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...

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

  • Utilisation de la valeur de 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 du composant de script.

Code du 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]);
    }
}

Faites glisser et déposez OLE DB Destination sur le flux de données languette. Connectez la flèche verte de Script Component vers Destination OLE DB . Double-cliquez sur Destination OLE DB pour ouvrir OLE DB Destination Editor .

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

  • Sélectionnez Sora à partir du Gestionnaire de connexion OLE DB
  • Sélectionnez Table or view - fast load depuis le mode d'accès aux données
  • Sélectionnez [dbo].[ProductListPrice] de Nom de la table ou de la vue
  • Cliquez sur Mappages pages

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

Flux de données devrait ressembler à ceci après avoir configuré tous les composants.

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

Exécutez le paquet. Vous remarquerez que le paquet a été traité avec succès 9 Lignes. Le fichier plat contient 10 lignes, mais la première ligne est un en-tête avec des noms de colonnes.

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

L'exemple ci-dessus illustre comment fractionner manuellement les données à l'aide de Script Component car le Gestionnaire de connexions de fichiers plats rencontre une 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 le délimiteur de colonne Ç , qui s'exécute mais rencontre un avertissement et ne traite aucune ligne.

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

  • Définir le nom du gestionnaire de connexion à ProductListPrice_Cedilla
  • Définissez 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 pages

Sur les Columns page de l'Éditeur du gestionnaire de connexions de fichiers plats , effectuez les actions suivantes :

  • Définir le délimiteur de ligne à {LF}
  • Le champ délimiteur de colonne peut être désactivé. Cliquez sur Reset Columns
  • Définir le délimiteur de colonne à Ç
  • Cliquez sur Advanced pages

Sur Advanced page de l'Éditeur du gestionnaire de connexions de fichiers plats , effectuez les actions suivantes :

  • Définir le Nom à ProductId
  • Définir le ColumnDelimiter à Ç
  • Définir le Type de données en Unicode string [DT_WSTR]
  • Définissez la longueur à 30
  • Cliquez sur la colonne ListPrice

Sur Advanced page de l'Éditeur du gestionnaire de connexions de fichiers plats , effectuez les actions suivantes :

  • Définir le Nom à ListPrice
  • Définir le ColumnDelimiter à {LF}
  • Définir le Type de données en numeric [DT_NUMERIC]
  • Définir la DataPrecision à 12
  • Définir la DataScale à 2
  • Cliquez sur OK

Faites glisser et déposez une Data Flow task sur le flux de contrôle tab et nommez-le comme File to database - With Cedilla delimiter . Désactivez la première tâche de flux de données.

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

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

Exécutez le paquet. Tous les composants s'afficheront en vert 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 la Flat File Source et OLE DB Destination

Cliquez sur 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.