2

複数のタスクを実行する SSIS パッケージがあります。OnExecStatusChanged イベントのパッケージ レベルで、Business Intelligence Studio 2005 内にイベント ハンドラを手動で追加しました。

私の質問は、C# 内でこのイベントのハンドラーを追加するにはどうすればよいですか? ここで指摘されているようにパッケージをロードし、「リスナー」である Microsoft.SqlServer.Dts.Runtime.DefaultEvents から継承されたカスタム クラスも作成しました。

    Microsoft.SqlServer.Dts.Runtime.SqlPackageEventListener sqlListener = new SqlPackageEventListener();
    Microsoft.SqlServer.Dts.Runtime.Application sqlPackageLoader = new Application();
    Microsoft.SqlServer.Dts.Runtime.Package sqlPackage = sqlPackageLoader.LoadPackage(@"path\MigrateData.dtsx", sqlListener);
    sqlPackage.Execute(null, null, sqlListener, null, null);

sqlPackage.EventHandlers.Count プロパティを確認すると、Business Intelligence Studio 内に追加されたハンドラーの正しい数を取得できます。

C# 内でこれらのイベントを処理する方法はありますか?

ありがとう。

4

1 に答える 1

4

何も見つからなかったので、回避策を考え出したので、自動応答します。

SSISパッケージが作成するイベントを直接キャッチする方法がないため、リスナー内に独自のイベントを実装しました。

public class SqlPackageEventListener : DefaultEvents
{
    public SqlPackageChangedHandler OnPackageError;

    public override bool OnError(DtsObject source, int errorCode, string subComponent, string description, string helpFile, int helpContext, string idofInterfaceWithError) {
        OnPackageError(this, new PackageErrorEventArgs(source, subComponent, description));
        return base.OnError(source, errorCode, subComponent, description, helpFile, helpContext, idofInterfaceWithError);
    }

    public delegate void SqlPackageChangedHandler(
        object sqlPackage,
        EventArgs packageInfo
        );
}

public class PackageErrorEventArgs : EventArgs 
{
    private DtsObject source;
    public DtsObject Source {
        get { return source; }
        set { source = value; }
    }

    private string subcomponent;
    public string Subcomponent {
        get { return subcomponent; }
        set { subcomponent = value; }
    }

    private string description;
    public string Description {
        get { return description; }
        set { description = value; }
    }

    public PackageErrorEventArgs(DtsObject source, string subcomponent, string description) {
        this.description = description;
        this.source = source;
        this.subcomponent = subcomponent;
    }
}

public class Test 
{
    SqlPackageEventListener sqlListener = new SqlPackageEventListener();
    sqlListener.OnPackageError += new SqlPackageEventListener.SqlPackageChangedHandler(sqlListener_OnPackageError);
    Microsoft.SqlServer.Dts.Runtime.Application sqlPackageLoader = new Microsoft.SqlServer.Dts.Runtime.Application();
    Microsoft.SqlServer.Dts.Runtime.Package sqlPackage = Microsoft.SqlServer.Dts.Runtime.sqlPackageLoader.LoadPackage(@"path_to\file.dtsx", sqlListener);
    sqlPackage.Execute(null, null, sqlListener, null, null)

    public void sqlListener_OnPackageError(object sender, EventArgs args) {
        //code to handle the event
    }
} 

したがって、「トリック」は、PackageオブジェクトのLoadPackageメソッドに渡す「Listener」オブジェクトにデリゲートを追加することです。これにより、リスナー内の「OnError」オーバーライドにアクセスして、イベントを発生させることができます。ご覧のとおり、私は独自のEventArgumentsクラスを実装して、重要なデータをハンドラーコードに渡し、実行中のパッケージや、DefaultEventsから継承するときにメソッドをオーバーライドすることで取得できるその他の情報を確認できるようにしました。

もちろん、ここではOnErrorのみを実装しました。SQLServerでサポートされている他のハンドラーを実装できます。これは、イベントを発生させるスコープであるため、オーバーライドできます。

そうすれば、SqlPackageEventListenerオブジェクトを作成し、その「OnPackageError」イベントをsqlListener_OnPackageErrorメソッドで処理し、SSISパッケージの実行によってエラーが発生した場合に必要な処理を実行できます。

于 2008-12-12T00:35:29.070 に答える