web-dev-qa-db-fra.com

SSIS: exécuter la première tâche si la condition est remplie sinon passez à la suivante

Je commence à connaître SSIS, je m'excuse si la question est trop simple.

J'ai un ensemble de tâches dans un foreach-loop -conteneur.
La première tâche doit seulement être exécutée à la condition qu'une certaine variable utilisateur n'est ni nulle ni vide.
Sinon, le flux devrait ignorer le premier tâche et passer au second.

Comment pourrais-je m'y prendre (en détail)?

8
David

Problème 1: Il existe deux manières d'interpréter votre logique: "... une certaine variable utilisateur n'est ni nulle ni vide":

  1. La (la variable n'est pas nulle) OR le (la variable est vide).
  2. La (la variable n'est pas nulle) OR le (la variable est non vide).

    Tout tourne autour de l'objet (s?) De la Parole "non". Les différences sont subtiles mais auront un impact lors de l'exécution de la première tâche de la boucle Foreach. À des fins de démonstration, je suppose que vous avez l’intention # 1.

    Problème 2: la première tâche ne peut plus être la première. Afin de réaliser ce que vous désirez en utilisant SSIS dans l’environnement BIDS, vous devez placer une autre tâche ahead de la tâche anciennement appelée "la première tâche". Cela vous permet de définir une contrainte de précédence sur l'ancienne première tâche à partir de la nouvelle première tâche. Il est possible de réaliser ce que vous désirez en concevant votre SSIS de manière dynamique à partir de code managé, mais je ne pense pas que ce problème justifie les frais généraux associés à ce choix de conception. J'aime utiliser un conteneur de séquence vide en tant que tâche "d'ancrage" - une tâche qui existe uniquement pour servir de point de départ pour une contrainte de précédence. Je les documente lourdement comme tels. Je ne veux pas que quelqu'un supprime le "contenant vide inutile" et parcourt les salles pendant des jours en secouant la tête et répétant "Andy, Andy, Andy ..." mais je m'éloigne du sujet.

    Dans l'exemple ci-dessous, j'ai deux contraintes de priorité qui laissent le conteneur de séquence vide. L'un va à la tâche qui peut être sautée et l'autre à la tâche qui suit la tâche qui peut parfois être sautée. Une troisième contrainte de priorité est requise entre la tâche qui peut parfois être ignorée et la tâche suivante. Il est important de noter que cette troisième contrainte de priorité doit être modifiée et que l'option Contraintes multiples doit être définie sur OU. Cela permet à la tâche suivante de s'exécuter lorsque l'un ou l'autre des chemins précédents mutuellement exclusifs est pris. Par défaut, cette option est définie sur AND et nécessite l'exécution de deux chemins. Par définition, cela ne se produira pas - can not - avec des chemins mutuellement exclusifs. 

    Je teste la valeur d'une variable de chaîne SSIS nommée @MyVar pour voir si elle est nulle ou vide. J'ai utilisé l'option d'évaluation Expression Only pour les contraintes quittant le conteneur de séquence vide. Les expressions varient mais établissent l'exclusivité mutuelle de l'expression. Mon conteneur de boucles Foreach ressemble à ceci:

 SSIS diagram

J'espère que ça aide.

: {>

15
Andy Leonard

La meilleure chose à faire peut être d'utiliser la propriété 'Désactiver' dans les expressions et de donner l'expression selon la condition. Il suffit de chercher comment utiliser la propriété disable.

8
Dibin

Qu'en est-il d'une solution simple au lieu de solutions plus complexes déjà proposées? Pour la tâche que vous souhaitez ignorer conditionnellement, ajoutez une expression à la propriété désactivée. Toute expression produisant un résultat vrai ou faux fonctionnera. Pour l'exemple de question, vous pouvez utiliser:

ISNULL(@[User::MY_VAR]) || @[User::MY_VAR]==""

Le seul inconvénient est qu’elle n’est peut-être pas aussi visible que d’autres solutions, mais elle est beaucoup plus simple à mettre en œuvre.

6
Dave Sexton

il n’est pas nécessaire de créer un "script" Je pense que la meilleure (et la plus simple) approche consiste à ajouter une tâche de script vide dans votre conteneur de boucles avant votre "première tâche", faites-la glisser vers votre "première" tâche "(qui deviendra évidemment la seconde) et utilisera la contrainte de priorité pour effectuer la vérification.

Pour ce faire, double-cliquez sur la flèche, sélectionnez "expression" dans "l'opération d'évaluation" et écrivez votre expression. Après avoir cliqué sur OK, la flèche devient bleue, indiquant qu'il ne s'agit pas d'une simple contrainte de précédence, mais d'une expression qui lui est affectée.

1
Diego

Je créerais un For Loop Container autour de la tâche qui nécessite la condition avec les conditions suivantes (@iest le compteur de boucles, @foo est la variable utilisateur que vous voulez tester):

  1. InitExpression : @i=0
  2. EvalExpression : @i<1 && !ISNULL(@Foo) && @Foo!=""
  3. AssignExpression : @i=@i+1
1
Ocaso Protal

C'est un peu délicat.

Vous devez créer une tâche de script et vérifier si votre variable n'est pas nulle.

Donc, vous avez d’abord la tâche de script dans laquelle vous aurez le code suivant dans votre fonction Main ():

public void Main()
{
    if (Dts.Variables["User::yourVariable"].Value != null)
    {
        Dts.TaskResult = (int)ScriptResults.Failure;
    }
    else
    {
        Dts.TaskResult = (int)ScriptResults.Success;
    }
}

Vous créez ensuite deux connexions à partir de votre tâche de script, l'une vers la tâche à exécuter lorsque votre variable n'est pas nulle et l'autre vers la tâche suivante (ou vers un autre script, si vous devez vérifier à nouveau, si la variable n'est pas nul).

Ensuite, vous faites un clic droit sur la flèche (verte) de votre première connexion et sélectionnez "Échec". Cliquez avec le bouton droit de la souris sur la connexion à la tâche/script suivante et définissez-la sur "Achèvement".

Cela devrait alors ressembler à quelque chose comme ça:

example

C'est tout.

0
fancyPants

J'espère que je n'ai pas mal compris la question, mais une solution possible peut être celle décrite ci-dessous.

J'ai créé un exemple de boucle ForEach. La boucle elle-même est un énumérateur d'élément. Il énumère les nombres 1, 2, 3. La valeur exacte est stockée dans une variable appelée LoopVariable.

Sample Foreach loop

Settings of the loop

Assigning to variable

Il existe une autre variable nommée FirstShouldRun qui est une variable booléenne indiquant que la première tâche de la boucle foreach doit être exécutée ou non. J'ai défini la propriété EvaluateAsExpression de cette variable sur true et son expression est (@[User::LoopVariable] % 2) == 0. Je voudrais démontrer avec cela que chaque première fois, la première tâche doit être lancée.

Variables

Setting of the property of the variable

Les deux tâches ne font rien beaucoup mais affichent un MessageBox indiquant que la tâche a été démarrée.

J'ai commencé le package et la première et la troisième fois, la première tâche ne commençait pas. Dans la seconde boucle, le MessageBox (montrant "First started") est apparu. 

Après cela, vous devez définir la variable FirstShouldRun à votre guise.

Comme je l'ai mentionné dans mon premier commentaire au PO, cette solution est basée sur l'idée d'Amos Wood écrite dans une autre réponse .

0
luviktor