Comment convertir L'ErrorCode et L'ErrorColumn dans SSIS en message d'erreur et nom de colonne?
je redirige des lignes à partir d'une source de fichier plate vers une destination de fichier plate. Les métadonnées par défaut dans les lignes redirigées sont:
- l'original de La source de fichier plat ligne
- The ErrorCode
- The ErrorColumn
ce que j'obtiens dans le fichier de sortie à plat est la ligne source (nice) et le code d'erreur (pas nice, ex. -1071628249) et la colonne d'erreur (pas agréable puisque c'est L'ID interne de la colonne).
Comment puis-je me transformer les lignes pour afficher le message d'erreur (par exemple "les données ont été tronquées.") et le nom de la colonne tel que défini dans la source de fichier plat?
En d'autres termes, au lieu de ...,-1071607675,10
j'aimerais voir:
...,The data was truncated,Firstname
ou sinon (si la précédente n'est pas possible);
...,DTS_E_FLATFILESOURCEADAPTERSTATIC_TRUNCATED,Firstname
.
8 réponses
une partie de la question (ajout de la description de l'erreur) peut être réalisée avec un composant script. Ceci est décrit dans amélioration D'une sortie D'erreur avec le composant Script.
Il semble que le Dougbert blog a une solution pour ajouter le nom de la colonne, mais il est loin d'être simple. Je suis étonné que ce soit si difficile à faire dans SSIS; vous penseriez que c'était un besoin fondamental de connaître le nom de la source et de la colonne.
liste des messages d'Erreur correspond à l'emplacement suivant: MSDN, services D'intégration référence D'erreur et de Message http://msdn.microsoft.com/en-us/library/ms345164%28v=sql.100%29.aspx
Et numéro d'identification de la colonne peut être trouvé dans la tâche de flux de données SSIS: sélectionnez le composant de tâche qui génère l'erreur, éditeur avancé, onglet "Propriétés D'entrée et de sortie", propriétés de colonnes externes.
Pragmatique Œuvres semble avoir un Sortie D'Erreur Description De Transformer c'est une partie de l' Édition Communautaire (Gratuit) du produit qu'ils appellent "usine à Tâches".
la transformation de description de sortie D'erreur fournit à l'utilisateur une Interface utilisateur qui peut récupérer des informations précieuses telles que L'ErrorCode, ErrorColumn, ErrorDescription, ComponentName (qui a généré l'erreur), ColumnName (si connu), ColumnType, et ColumnLength.
il vous permet également de passer à travers n'importe quelles colonnes d'entrée à la sortie D'erreur. Pour être honnête, il est très pratique et m'a permis de gagner des heures de dépannage de mes paquets SSIS.
il y a une réponse beaucoup plus simple. Il suffit de rediriger la sortie d'erreur vers un nouveau fichier de destination (CSV ou autre), puis d'activer un DataViewer sur la sortie d'erreur....
cela peut être réalisé en utilisant script component comme transformation, rediriger la sortie d'erreur vers le script component et suivre les étapes pour atteindre ce que vous recherchez.
(1) Ouvrez le composant de script ,
colonnes D'entrée choisir
- ErrorColumn
- ErrorCode
Entrée et de Sortie ajouter des colonnes de Sortie
- ErrorDescription (DT_STRING 500)
- ErrorColumnDescription (DT_STRING 100)
(2) Modifier Le Script
Coller le code suivant
using System;
using System.Data;
using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
using Microsoft.SqlServer.Dts.Runtime.Wrapper;
#endregion
/// <summary>
/// This is the class to which to add your code. Do not change the name, attributes, or parent
/// of this class.
/// </summary>
[Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute]
public class ScriptMain : UserComponent
{
public override void Input0_ProcessInputRow(Input0Buffer Row)
{
var component130 = this.ComponentMetaData as IDTSComponentMetaData130;
if (component130 != null)
{
Row.ErrorDescription = component130.GetErrorDescription(Row.ErrorCode);
Row.ErrorColumnDescription = component130.GetIdentificationStringByID(Row.ErrorColumn);
}
}
//column error description
Row.ErrorDescription = this.ComponentMetaData.GetErrorDescription(Row.ErrorCode);
//we are getting column name with some extra information
String rawColumnName = this.ComponentMetaData.GetIdentificationStringByLineageID(Row.ErrorColumn);
//extracting positions of brackets
int bracketPos = rawColumnName.LastIndexOf('[')+1;
int lastBracketPos = rawColumnName.LastIndexOf(']');
//extracting column name from the raw column name
Row.ErrorColName = rawColumnName.Substring(bracketPos, (lastBracketPos - bracketPos));
Voici une solution qui
- Fonctionne au forfait d'exécution (pas de pré-remplissage)
- est automatisée par une tâche et un composant de Script
- N'implique pas l'installation de nouveaux assemblages ou composants personnalisés
- Est joliment BIML compatible
consultez la solution complète ici.
Voici la version courte.
- Créer 2 variables d'Objet,
execsObj
etlineageIds
- créer la tâche Script dans le flux de contrôle, lui donner L'accès ReadWrite aux deux variables
- insérez le code suivant dans votre tâche Script
Dictionary<int, string> lineageIds = null;
public void Main()
{
// Grab the executables so we have to something to iterate over, and initialize our lineageIDs list
// Why the executables? Well, SSIS won't let us store a reference to the Package itself...
Dts.Variables["User::execsObj"].Value = ((Package)Dts.Variables["User::execsObj"].Parent).Executables;
Dts.Variables["User::lineageIds"].Value = new Dictionary<int, string>();
lineageIds = (Dictionary<int, string>)Dts.Variables["User::lineageIds"].Value;
Executables execs = (Executables)Dts.Variables["User::execsObj"].Value;
ReadExecutables(execs);
Dts.TaskResult = (int)ScriptResults.Success;
}
private void ReadExecutables(Executables executables)
{
foreach (Executable pkgExecutable in executables)
{
if (object.ReferenceEquals(pkgExecutable.GetType(), typeof(Microsoft.SqlServer.Dts.Runtime.TaskHost)))
{
TaskHost pkgExecTaskHost = (TaskHost)pkgExecutable;
if (pkgExecTaskHost.CreationName.StartsWith("SSIS.Pipeline"))
{
ProcessDataFlowTask(pkgExecTaskHost);
}
}
else if (object.ReferenceEquals(pkgExecutable.GetType(), typeof(Microsoft.SqlServer.Dts.Runtime.ForEachLoop)))
{
// Recurse into FELCs
ReadExecutables(((ForEachLoop)pkgExecutable).Executables);
}
}
}
private void ProcessDataFlowTask(TaskHost currentDataFlowTask)
{
MainPipe currentDataFlow = (MainPipe)currentDataFlowTask.InnerObject;
foreach (IDTSComponentMetaData100 currentComponent in currentDataFlow.ComponentMetaDataCollection)
{
// Get the inputs in the component.
foreach (IDTSInput100 currentInput in currentComponent.InputCollection)
foreach (IDTSInputColumn100 currentInputColumn in currentInput.InputColumnCollection)
lineageIds.Add(currentInputColumn.ID, currentInputColumn.Name);
// Get the outputs in the component.
foreach (IDTSOutput100 currentOutput in currentComponent.OutputCollection)
foreach (IDTSOutputColumn100 currentoutputColumn in currentOutput.OutputColumnCollection)
lineageIds.Add(currentoutputColumn.ID, currentoutputColumn.Name);
}
}
4. Créez le composant Script dans Dataflow avec un accès en lecture seule à lineageIds
et le code suivant.
public override void Input0_ProcessInputRow(Input0Buffer Row)
{
Dictionary<int, string> lineageIds = (Dictionary<int, string>)Variables.lineageIds;
int? colNum = Row.ErrorColumn;
if (colNum.HasValue && (lineageIds != null))
{
if (lineageIds.ContainsKey(colNum.Value))
Row.ErrorColumnName = lineageIds[colNum.Value];
else
Row.ErrorColumnName = "Row error";
}
Row.ErrorDescription = this.ComponentMetaData.GetErrorDescription(Row.ErrorCode);
}
je me suis connecté à la page Web du message d'erreur ref de SSIS avec excel en utilisant les données get du web dans l'onglet Données. A enregistré la table dans une feuille dans excel, puis l'a importée dans SQL Server. Puis je l'ai joint à ma table de lignes d'erreur sur le code décimal pour obtenir la description, puis j'ai créé une vue à partir de celle-ci. J'ai pensé que cela pourrait être utile pour ceux qui ne veulent pas jouer avec la tâche script.