2009-09-29 37 views
2

J'ai une tâche de script qui effectue des transformations au milieu d'un flux de données SSIS. Si le script échoue (disons qu'il essaie de convertir alpha en numérique), j'en ai besoin pour arrêter avec un statut 'échoué' et retourner au paquet principal puis utiliser le gestionnaire d'événements de tâche Dataflow OnError pour quitter normalement. À l'heure actuelle, je trouve que la tâche de script dans le flux de données renvoie une fenêtre d'erreur .net que je dois effacer ensuite. J'ai essayé un Try Catch autour du code qui semble arrêter la fenêtre de débogage, mais je n'arrive pas à l'obtenir pour quitter le script avec un 'statut échoué' qui fera échouer le paquet. Le Dts.TaskResult = Dts.Results.Failure ne semble pas être valide dans les tâches de flux de données. En ce moment j'essaye ceci:Traitement des erreurs de tâche de script SSIS Dataflow

Catch e As System.Exception 
     Me.ComponentMetaData.FireError(-1, "", "Error: ", e.Message, 1, True) 
     While Not e.InnerException Is Nothing 
      e = e.InnerException 
      Me.ComponentMetaData.FireError(-1, "", "InnerException: ", e.Message, 1, True) 
     End While 
     Exit Sub 
    End Try 

... mais tout cela fait est passer la mauvaise rangée. Le flux de données continue. Le problème est de le faire sortir comme 'échoué' donc l'événement de gestionnaire d'erreur onError dans le paquet est déclenché.

Toute suggestion reçue avec gratitude. Glenn

+1

BTW, si elle est dans un flux de données, il est un composant de script, pas une tâche de script. –

Répondre

3

Les transformations de script n'ont pas les mêmes caractéristiques pour le succès ou l'échec du retour. Vous pouvez forcer une erreur en utilisant ce code:

If Row.TestColumn = "Value I Want To Error On" Then 
     Error (1) 
    End If 

En fait, l'objet d'erreur (? Fonction méthode quel que soit!) Vous permettra de simuler une erreur. Signification, vous pouvez faire l'erreur de paquet avec ce code.

+0

Merci. En guise de suivi, je me rends compte qu'une certaine confusion régnait à ma fin. L'erreur contextuelle est en fait souhaitable et probablement nécessaire pour que le client connaisse le problème. J'ai abandonné tout mon code Try Catch dans le script et laissé le paquet échouer par lui-même, et quand je l'ai lancé dans le frontend la fenêtre de débogage dans VS a été remplacée par une erreur web (qui est OK) et le backend l'événement OnError (qui nettoie certaines tables). La confusion est venue par le besoin de cliquer sur OK dans VS pour effacer l'erreur, mais bien sûr ce n'est pas une exigence lorsque vous exécutez le paquet en dehors de VS. –

+0

Vous avez raison de dire que la suppression du bloc Try Catch permettra aux échecs d'échouer automatiquement. Je suis tombé sur cette question il y a environ un mois et j'en suis arrivé à la même conclusion. Je suis d'abord venu à la solution en forçant une erreur dans le bloc Try Catch. Puis j'ai ajouté une erreur dans le bloc Catch. Dès que j'ai eu cette erreur, j'ai réalisé que le problème était le bloc Try Catch. Laissez SSIS gérer l'exception au lieu de la gérer vous-même. –

0

J'ai cherché pendant un certain temps à la réponse à cette question. L'erreur de popup est juste trop ennuyante pour moi! Pour éviter cela, une solution "simple" (hack) est la suivante:

Plutôt que de lancer une erreur après le .FireError, créez une nouvelle colonne de sortie DT_UI1 dans la transformation de script, par ex. "ValidationColumn", et réglez-le sur 1 ou 0 (Non booléen pour des raisons qui deviendront claires).

Immédiatement après le composant de script, ajoutez une transformation de colonne dérivée et remplacez ValidationColumn par la formule: 1/ValidationColumn. (Cela ne fonctionne pas avec Boolean). Ceci, bien sûr, a généré une erreur de division par zéro et (en utilisant le paramètre par défaut) échoue la transformation de colonne dérivée et donc immédiatement le composant de flux de données. Voila!

Le journal des erreurs a le message d'échec de validation d'origine provenant de .FireError, immédiatement suivi d'une erreur de division par zéro.

Cela peut être un hack, mais jusqu'à ce que quelqu'un arrive avec une meilleure idée ...

BTW, j'utilise cette option pour vérifier que les fichiers Excel ont les en-têtes corrects dans le bon endroit (ou autres lieux) , en conjonction avec l'utilisation IMEX = 1, afin de charger 2 ou plusieurs variations de colonnes différentes en utilisant un seul flux de données ...

1

Rétrospectivement, l'erreur de division par zéro n'est pas nécessaire.

Dans ma solution actuelle, je suis capturant l'erreur, puis en faisant un FireError, réimplémentant alors la gestion des exceptions, comme ceci:

If excludeHeader = -1 Then 
    'Throw New InvalidDataException("Invalid exclude column: " & Variables.excludeColumn) 
    ComponentMetaData.FireError(0, ComponentMetaData.Name.Trim(), "Invalid exclude column: " & Variables.excludeColumn, String.Empty, 0, True) 
    excelConnection.Close() 
    excelConnection.Dispose() 
    Return 
End If 

Cela fonctionne parce qu'il est contenu dans un script source et que vous aussi travailler dans un script de transformation fournissant le flux de données a été défini pour échouer après 1 erreur.Sinon, le script aurait besoin d'implémenter un chemin de sortie d'erreur que, franchement, je n'ai pas le temps de ...

0

Voici une tâche de script que j'ai créée à l'intérieur d'une boucle. Ce n'est pas une réponse directe à votre question - mais l'idée générale aidera.

La tâche de script est conservée dans un conteneur de séquence. Et le variable du conteneur de séquence nommé Propagate est défini comme faux. En outre, pour la propriété sequence container, la propriété MaximumErrorCount est définie sur zéro. Ainsi, lorsqu'une erreur survient à l'intérieur du conteneur de séquence, elle est affichée en rouge, l'événement OnError est déclenché - mais la boucle est poursuivie. Il est important de créer un gestionnaire d'événement onerror pour que le conteneur de séquence fonctionne.

A l'intérieur de la tâche de script, il échoue de force dans le bloc catch (en définissant le résultat de la tâche sur Echec). Le message d'exception est également stocké dans une variable pour le stocker dans la table de consignation des erreurs. Cette insertion de données d'erreur se produit à partir de la tâche sql execute du gestionnaire d'événement OnError (mentionné ci-dessus).

Référez: MSDN - ScriptObjectModel.TaskResult Property

Utilisez la propriété TaskResult de l'objet Dts dans le code de tâche de script pour informer le package de la réussite ou l'échec de la tâche de script.

Le bloc catch dans la tâche de script ressemble à celui indiqué ci-dessous.

Catch ex As Exception 

     Dim exceptionVariable As Microsoft.SqlServer.Dts.Runtime.Variables = Nothing 
     Dts.VariableDispenser.LockOneForWrite("User::ScriptException", exceptionVariable) 
     exceptionVariable("User::CustomScriptException").Value = ex.Message 
     exceptionVariable.Unlock() 
     Dts.Events.FireError(-1, "Task Name", ex.Message, [String].Empty, 0) 
     Dts.TaskResult = Dts.Results.Failure 
    End Try 

Flow Control

enter image description here