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.

24
demandé sur Bernhard Hofmann 2012-10-02 19:46:46
la source

8 ответов

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.

13
répondu Bernhard Hofmann 2012-10-03 13:08:06
la source

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.

12
répondu Perdi Estaquel 2014-01-31 04:16:46
la source

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.

4
répondu Tyler Ryan 2013-06-03 23:37:15
la source

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

Data Viewer in SSIS

3
répondu kevin plunkett 2016-09-02 12:57:10
la source

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

  1. ErrorColumn
  2. ErrorCode

Entrée et de Sortie ajouter des colonnes de Sortie

  1. ErrorDescription (DT_STRING 500)
  2. 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);
            }
        }
3
répondu Sathyanath G 2017-07-27 08:45:21
la source
    //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));
2
répondu observer 2016-02-29 16:14:29
la source

Voici une solution qui

  1. Fonctionne au forfait d'exécution (pas de pré-remplissage)
  2. est automatisée par une tâche et un composant de Script
  3. N'implique pas l'installation de nouveaux assemblages ou composants personnalisés
  4. Est joliment BIML compatible

consultez la solution complète ici.


Voici la version courte.

  1. Créer 2 variables d'Objet, execsObj et lineageIds
  2. créer la tâche Script dans le flux de contrôle, lui donner L'accès ReadWrite aux deux variables
  3. 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);
  }
1
répondu sorrell 2015-10-31 05:30:03
la source

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.

1
répondu Brandon Frenchak 2018-06-26 00:38:58
la source

Autres questions sur