[SSIS] Concaténer les valeurs d’une ligne de données

Petit besoin intéressant: vouloir reproduire le fonctionnement des sources de Data Flow en concaténant les valeurs de toutes les colonnes d’une ligne de Pipeline dans une colonne unique (à des fins de log par exemple, pour tout mettre dans une seule table SQL).

La technique n’est pas très compliquée, il suffit de savoir comment s’y prendre au départ.
Tout d’abord il faut que le composant soit dynamique: cela veut dire que le script doit marcher pour tout buffer d’entrée. Cela élimine immédiatement la méthode ProcessInputRow(ScriptBuffer) au détriment de ProcessInput(PipelineBuffer). Il est en effet impossible d’accéder à une ligne d’un ScriptBuffer via une méthode générique, il faut utiliser des accesseurs qui portent le nom de la colonne, que par essence on ne connaît pas (et j’annonce: la Reflection n’est pas une option ici, même si la première fois que j’ai codé ce script je l’ai fait comme ça…).
Donc pour travailler avec un PipelineBuffer il faut connaître l’index de la colonne à récupérer: bonne pioche, le Script Component bénéficie d’une méthode GetColumnIndexes() qui renvoie les indexes des colonnes d’un Input100 ou Output100. Une fois ces indexes récupérés, on a plus qu’à concaténer avec un StringBuilder.
Le code (simplissime) est ci-dessous (à noter que je n’ai qu’une seule colonne dans mon Output100: ma valeur de concaténation).
public class ScriptMain : UserComponent
{
private int[] columnIndexes;
private int outputColumnIndex;
public override void PreExecute()
{
base.PreExecute();
columnIndexes = this.GetColumnIndexes(this.ComponentMetaData.InputCollection[0].ID);
outputColumnIndex = this.GetColumnIndexes(this.ComponentMetaData.OutputCollection[0].ID)[0];
}

private string RowConcat(PipelineBuffer b, int[] columnIndexes, char separator)
{
StringBuilder sb = new StringBuilder();
foreach (int columnIndex in columnIndexes)
{
if (b[columnIndex] != null)
sb.Append(b[columnIndex].ToString());
sb.Append(separator);
}
return sb.ToString();
}

public override void ProcessInput(int InputID, PipelineBuffer Buffer)
{
while (Buffer.NextRow())
{
Buffer.SetString(outputColumnIndex, RowConcat(Buffer,columnIndexes,';'));
}
}
}

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s