2017-08-18 1 views
0

En utilisant SSIS, j'importe un fichier .txt qui, pour la plupart, est simple.SSIS Merge Variables Colonnes

Le fichier en cours d'importation a une quantité définie de colonnes jusqu'à un point, mais il existe un champ de texte/commentaires libre, qui peut se répéter jusqu'à une longueur inconnue, comme ci-dessous.

"000001","J Smith","Red","Free text here" 
    "000002","A Ball","Blue","Free text here","but can","continue" 
    "000003","W White","Green","Free text here","but can","continue","indefinitely" 
    "000004","J Roley","Red","Free text here" 

Ce que je voudrais idéalement faire (dans les SSIS) est de maintenir les trois premières colonnes que des colonnes singulières, mais de fusionner tout les texte libre en une seule colonne. C'est-à-dire Fusionner/concaténer tout ce qui apparaît après la colonne 'color'.

Alors, quand je charge ce dans une table SSMS, il apparaît comme:

000001 | J Smith | Red | Free text here          | 
000002 | A Ball | Blue | Free text here but can continue     | 
000003 | W White | Green | Free text here but can continue indefinitely  | 
000004 | J Roley | Red | Free text here          | 

Répondre

0

Je ne vois pas de solution facile. Vous pouvez essayer quelque chose comme ci-dessous:

1. Chargez les données brutes complètes à une table temporaire (sans séparateur):

étapes:

  1. Créer table temporaire dans Exécuter SQL Tâche
  2. Créer une tâche de flux de données, avec une source de fichier plat (au format Ragged Right) et
  3. OLEDB destination (la table usint #temp a été créée précédemment tâche)
  4. Définissez le delayValidation=True pour le gestionnaire de connexion et DFT
  5. Set retainSameConnection=True pour le gestionnaire de connexion

Reportez-vous this pour créer table temporaire et l'utiliser.

2. Créez T-SQL pour séparer les 3 colonnes (quelque chose comme ci-dessous)

with col1 as (
    Select 
    [Val], 
    substring([Val], 1 ,charindex(',', [Val]) - 1) col1, 
    len(substring([Val], 1 ,charindex(',', [Val]))) + 1 col1Len 
    from #temp 
), col2 as (
    select 
    [Val], 
    col1, 
    substring([Val], col1Len, charindex(',', [Val], col1Len) - col1Len) as col2, 
    charindex(',', [Val], col1Len) + 1 col2Len 
    from col1 
) select col1, col2, substring([Val], col2Len, 200) as col3 
from col2 

sortie T-SQL:

col1 col2 col3 
"000001" "J Smith" "Red","Free text here" 
"000002" "A Ball" "Blue","Free text here","but can","continue" 
"000003" "W White" "Green","Free text here","but can","continue","indefinitely" 

3. Utilisez la requête ci-dessus dans la source OLEDB dans différentes tâche de flux de données

Remplacez les guillemets (") selon vos besoins.

0

Ce fut un exercice amusant:

Ajouter un flux de données

Ajouter un composant Script (sélectionnez source)

Ajouter 4 colonnes à sorties ID, Nom couleur, FreeText toutes les chaînes de type

script edit:

Coller les espaces de noms suivants en haut:

using System.Text.RegularExpressions; 
using System.Linq; 

Collez le code suivant dans CreateNewOutputRows:

string strPath = @"a:\test.txt"; \\put your file path in here 
    var lines = System.IO.File.ReadAllLines(strPath); 

    foreach (string line in lines) 
    { 
     //Code I stole to read CSV 
     string delimeter = ","; 

     Regex rgx = new Regex(String.Format("(\"[^\"]*\"|[^{0}])+", delimeter)); 
     var cols = rgx.Matches(line) 
         .Cast<Match>() 
         .Select(m => m.Value.Trim().Trim('"')) 
         .Where(v => !string.IsNullOrWhiteSpace(v)); 
     //create a column counter 
     int ctr = 0; 

     Output0Buffer.AddRow(); 

     //Preset FreeText to empty string 
     string FreeTextBuilder = String.Empty; 

     foreach(string col in cols) 
     { 

      switch (ctr) 
      { 
       case 0: 
        Output0Buffer.ID = col; 
        break; 
       case 1: 
        Output0Buffer.Name = col; 
        break; 
       case 2: 
        Output0Buffer.Color = col; 
        break; 
       default: 
        FreeTextBuilder += col + " "; 
        break; 
      } 
      ctr++; 
     } 

     Output0Buffer.FreeText = FreeTextBuilder.Trim(); 

    }