私はSSISについて知っています。質問が単純すぎると申し訳ありません。
内部のタスクのセット foreach-loop -containerを取得しました。
最初のタスクを実行する必要があるだけ条件付き特定のユーザー変数がnullまたは空ではないであること。
それ以外の場合、フローはスキップする最初にタスクで、2番目のフローに進む必要があります。
方法これを(詳細に)実現しようと思いますか?
問題1:ロジックを解釈するには2つの方法があります。「...特定のユーザー変数がnullまたは空ではない」:
(変数はnullではない)OR(変数は空ではない)。
それはすべて、「ではない」という言葉の目的についてです。違いはわずかですが、Foreachループの最初のタスクが実行されるときに影響します。デモンストレーションの目的で、私はあなたが#1を意図していると想定しています。
問題2:最初のタスクを最早にすることはできません。 BIDS環境内でSSISを使用して希望どおりの結果を得るには、以前は「最初のタスク」と呼ばれていたタスクの別のタスクを先に配置する必要があります。 。これは、新しい最初のタスクから以前の最初のタスクに優先順位制約を設定できるようにするためです。マネージコードからSSISを動的に設計することで、目的を達成することは可能ですが、この問題がその設計の選択に関連するオーバーヘッドを保証するものではないと思います。空のシーケンスコンテナーを「アンカー」タスクとして使用するのが好きです-優先順位制約の開始エンドポイントとしてのみ機能するタスク。私はそれらをそのように文書化しています。 「不要な空のコンテナ」を削除して、何日もホールをローミングして頭を振ったり、「アンディ、アンディ、アンディ...」を繰り返したりしたくないのですが、私は余談です。
以下の例では、2つの優先順位制約があり、空のシーケンスコンテナーが残っています。 1つはスキップされる可能性のあるタスクに移動し、もう1つは、スキップ可能なタスクに続くタスクに移動します。 3番目の優先順位制約は、スキップできるタスクと後続のタスクの間に必要です。この3番目の優先順位制約を編集して、[複数の制約]オプションをORに設定する必要があることに注意してください。これにより、相互に排他的な以前のパスのいずれかが使用されたときに、後続のタスクを実行できます。デフォルトでは、これはANDに設定されており、実行にはbothパスが必要です。定義上、これは-できませんできません-相互に排他的なパスでは発生しません。
@MyVarという名前のSSIS文字列変数の値をテストして、それがNullまたは空かどうかを確認します。空のシーケンスコンテナーを残す制約に式のみの評価オプションを使用しました。表現はさまざまですが、表現の相互排他性を確立します。私のForeachループコンテナーは次のようになります。
これがお役に立てば幸いです。
:{>
最良のものは、式で「プロパティを無効にする」を使用し、条件に従って式を与えることです。 disableプロパティの使用方法を検索するだけです。
すでに与えられているいくつかのより複雑なものの代わりに単純な解決策はどうですか?条件付きでスキップするタスクについて、無効化されたプロパティに式を追加します。 trueまたはfalseの結果を生成する任意の式が機能するため、質問の例では次のように使用できます。
ISNULL(@[User::MY_VAR]) || @[User::MY_VAR]==""
唯一の欠点は、他のソリューションほどは見えないかもしれませんが、実装がはるかに簡単です。
「スクリプト」を作成する必要はありません。最良の(そしてより簡単な)アプローチは、「最初のタスク」の前にループコンテナー内に空白のスクリプトタスクを追加し、緑色の矢印を「最初のタスク」(これは明らかに2番目になります)、優先順位制約を使用してチェックを行います。
そのためには、矢印をダブルクリックし、「評価操作」で「式」を選択して、式を記述します。 [OK]をクリックすると、矢印が青色になり、単純な優先制約ではなく、式が割り当てられていることを示します。
私は次の条件で条件を必要とするタスクの周りに_For Loop Container
_を作成します(_@i
_はループカウンター、_@foo
_はテストするユーザー変数です):
@i=0
_@i<1 && !ISNULL(@Foo) && @Foo!=""
@i=@i+1
_それは少しトリッキーです。
スクリプトタスクを作成し、変数がnullでないかどうかを確認する必要があります。
したがって、最初にスクリプトタスクを作成し、Main()関数に次のコードを含めます。
public void Main()
{
if (Dts.Variables["User::yourVariable"].Value != null)
{
Dts.TaskResult = (int)ScriptResults.Failure;
}
else
{
Dts.TaskResult = (int)ScriptResults.Success;
}
}
次に、スクリプトタスクから2つの接続を作成します。1つは変数がnullでない場合に実行する必要があるタスクへの接続で、もう1つは次のタスク(または、変数をチェックする必要がある場合は別のスクリプトへの接続)です。ヌル)。
次に、最初の接続の(緑色の)矢印を右クリックし、[失敗]を選択します。次のタスク/スクリプトへの接続を右クリックして、「完了」に設定します。
その後、次のようになります。
それでおしまい。
うまくいけば、私は質問を誤解しなかったが、可能な解決策は以下に書かれているようにすることができます。
ForEachループのサンプルを作成しました。ループ自体はアイテムの列挙子です。数値1、2、3を列挙します。実際の値は、LoopVariable
という変数に格納されます。
FirstShouldRun
という名前の別の変数があります。これは、foreachループの最初のタスクを実行するかどうかを示すブール変数です。この変数のEvaluateAsExpressionプロパティをtrueに設定し、その式は(@[User::LoopVariable] % 2) == 0
。これで、最初のタスクを2回おきに開始する必要があることを示したいと思います。
2つのタスクは、タスクが開始されたことを示すメッセージボックスを表示するだけで、ほとんど何もしません。
パッケージを開始したところ、最初と3回目に最初のタスクが開始されませんでした。 2番目のループでは、メッセージボックス("First started"
)登場。
その後、必要に応じてFirstShouldRun
変数を設定する必要があります。
OPへの最初のコメントで述べたように、このソリューションは 別の回答 で記述されたAmos Woodのアイデアに基づいています。