プログラムによるイベントの処理
SSIS のランタイムには、パッケージの検証や実行の処理前、処理中、処理後に発生する一連のイベントがあります。 これらのイベントをキャプチャするには、次の 2 つの方法があります。 1 つは、あるクラスに IDTSEvents インターフェイスを実装し、このクラスをパラメーターとして、パッケージの Execute メソッドおよび Validate メソッドに渡す方法です。 もう 1 つは DtsEventHandler オブジェクトを作成する方法です。このオブジェクトには、タスクやループなど、IDTSEvents に属するイベントが発生したときに実行される、他の SSIS オブジェクトを含めることができます。 ここでは、この 2 つの方法について説明し、その使用法をコード例で示します。
IDTSEvents コールバックの受信
プログラムによってパッケージを構築し、実行する開発者は、IDTSEvents インターフェイスを使用して、検証中や実行中に発生したイベント通知を受信することができます。 これを行うには、IDTSEvents インターフェイスを実装したクラスを作成し、このクラスをパラメーターとして、パッケージの Validate メソッドおよび Execute メソッドに渡します。 イベントが発生すると、ランタイム エンジンによってこのクラスのメソッドが呼び出されます。
DefaultEvents クラスにはあらかじめ IDTSEvents インターフェイスが実装されています。したがって、IDTSEvents インターフェイスを直接実装する代わりに、DefaultEvents から派生するクラスを作成し、応答を受ける特定のイベントをオーバーライドする方法を取ることもできます。 その後、このクラスをパラメーターとして、Package の Validate メソッドおよび Execute メソッドに渡し、イベントのコールバックを受け取ります。
次のコード サンプルは、DefaultEvents から派生するクラスを示し、OnPreExecute メソッドをオーバーライドします。 クラスはパラメーターとして、パッケージの Validate メソッドおよび Execute メソッドに渡されます。
using System;
using Microsoft.SqlServer.Dts.Runtime;
namespace Microsoft.SqlServer.Dts.Samples
{
class Program
{
static void Main(string[] args)
{
Package p = new Package();
MyEventsClass eventsClass = new MyEventsClass();
p.Validate(null, null, eventsClass, null);
p.Execute(null, null, eventsClass, null, null);
Console.Read();
}
}
class MyEventsClass : DefaultEvents
{
public override void OnPreExecute(Executable exec, ref bool fireAgain)
{
// TODO: Add custom code to handle the event.
Console.WriteLine("The PreExecute event of the " +
exec.ToString() + " has been raised.");
}
}
}
Imports Microsoft.SqlServer.Dts.Runtime
Module Module1
Sub Main()
Dim p As Package = New Package()
Dim eventsClass As MyEventsClass = New MyEventsClass()
p.Validate(Nothing, Nothing, eventsClass, Nothing)
p.Execute(Nothing, Nothing, eventsClass, Nothing, Nothing)
Console.Read()
End Sub
End Module
Class MyEventsClass
Inherits DefaultEvents
Public Overrides Sub OnPreExecute(ByVal exec As Executable, ByRef fireAgain As Boolean)
' TODO: Add custom code to handle the event.
Console.WriteLine("The PreExecute event of the " & _
exec.ToString() & " has been raised.")
End Sub
End Class
DtsEventHandler オブジェクトの作成
ランタイム エンジンには、DtsEventHandler オブジェクトを介した、堅牢で柔軟性の高いイベント処理/通知システムが含まれています。 このオブジェクトを使用すると、イベント ハンドラー内のワークフロー全体をデザインして、そのイベント ハンドラーが属するイベントが発生したときにのみ、ワークフローを実行させることができます。 DtsEventHandler はコンテナー オブジェクトで、親オブジェクト内の対応するイベントが発生すると実行されます。 したがって、コンテナー上で発生したイベントに応答して実行されるワークフローを、他のワークフローとは独立して作成できます。 DtsEventHandler オブジェクトは同期型であるため、イベントにアタッチされたイベント ハンドラーが返されるまで、実行は再開されません。
次のコードは、DtsEventHandler オブジェクトの作成方法を示しています。 コードは、FileSystemTask をパッケージの Executables コレクションに追加し、次にタスクの OnError イベント用の DtsEventHandler オブジェクトを作成します。 FileSystemTask がイベント ハンドラーに追加されます。これは、最初の FileSystemTask に対する OnError イベントが発生したときに行われます。 この例では、C:\Windows\Temp\DemoFile.txt という名前のファイルをテストに使用することを前提にしています。 サンプルを初めて実行するとき、ファイルが正常にコピーされていれば、イベント ハンドラーは呼び出されません。 2 回目にサンプルを実行すると、最初の FileSystemTask はファイルのコピーに失敗し (OverwriteDestinationFile の値が false であるため)、イベント ハンドラーが呼び出され、2 番目の FileSystemTask によって変換元ファイルが削除され、エラーの発生が原因でパッケージによって失敗が報告されます。
例
using System;
using System.IO;
using Microsoft.SqlServer.Dts.Runtime;
using Microsoft.SqlServer.Dts.Tasks.FileSystemTask;
namespace Microsoft.SqlServer.Dts.Samples
{
class Program
{
static void Main(string[] args)
{
string f = "DemoFile.txt";
Executable e;
TaskHost th;
FileSystemTask fst;
Package p = new Package();
p.Variables.Add("sourceFile", true, String.Empty,
@"C:\Windows\Temp\" + f);
p.Variables.Add("destinationFile", true, String.Empty,
Path.Combine(Directory.GetCurrentDirectory(), f));
// Create a first File System task and add it to the package.
// This task tries to copy a file from one folder to another.
e = p.Executables.Add("STOCK:FileSystemTask");
th = e as TaskHost;
th.Name = "FileSystemTask1";
fst = th.InnerObject as FileSystemTask;
fst.Operation = DTSFileSystemOperation.CopyFile;
fst.OverwriteDestinationFile = false;
fst.Source = "sourceFile";
fst.IsSourcePathVariable = true;
fst.Destination = "destinationFile";
fst.IsDestinationPathVariable = true;
// Add an event handler for the FileSystemTask's OnError event.
DtsEventHandler ehOnError = (DtsEventHandler)th.EventHandlers.Add("OnError");
// Create a second File System task and add it to the event handler.
// This task deletes the source file if the event handler is called.
e = ehOnError.Executables.Add("STOCK:FileSystemTask");
th = e as TaskHost;
th.Name = "FileSystemTask2";
fst = th.InnerObject as FileSystemTask;
fst.Operation = DTSFileSystemOperation.DeleteFile;
fst.Source = "sourceFile";
fst.IsSourcePathVariable = true;
DTSExecResult vr = p.Validate(null, null, null, null);
Console.WriteLine("ValidationResult = " + vr.ToString());
if (vr == DTSExecResult.Success)
{
DTSExecResult er = p.Execute(null, null, null, null, null);
Console.WriteLine("ExecutionResult = " + er.ToString());
if (er == DTSExecResult.Failure)
if (!File.Exists(@"C:\Windows\Temp\" + f))
Console.WriteLine("Source file has been deleted by the event handler.");
}
Console.Read();
}
}
}
Imports System.IO
Imports Microsoft.SqlServer.Dts.Runtime
Imports Microsoft.SqlServer.Dts.Tasks.FileSystemTask
Module Module1
Sub Main()
Dim f As String = "DemoFile.txt"
Dim e As Executable
Dim th As TaskHost
Dim fst As FileSystemTask
Dim p As Package = New Package()
p.Variables.Add("sourceFile", True, String.Empty, _
"C:\Windows\Temp\" & f)
p.Variables.Add("destinationFile", True, String.Empty, _
Path.Combine(Directory.GetCurrentDirectory(), f))
' Create a first File System task and add it to the package.
' This task tries to copy a file from one folder to another.
e = p.Executables.Add("STOCK:FileSystemTask")
th = CType(e, TaskHost)
th.Name = "FileSystemTask1"
fst = CType(th.InnerObject, FileSystemTask)
fst.Operation = DTSFileSystemOperation.CopyFile
fst.OverwriteDestinationFile = False
fst.Source = "sourceFile"
fst.IsSourcePathVariable = True
fst.Destination = "destinationFile"
fst.IsDestinationPathVariable = True
' Add an event handler for the FileSystemTask's OnError event.
Dim ehOnError As DtsEventHandler = CType(th.EventHandlers.Add("OnError"), DtsEventHandler)
' Create a second File System task and add it to the event handler.
' This task deletes the source file if the event handler is called.
e = ehOnError.Executables.Add("STOCK:FileSystemTask")
th = CType(e, TaskHost)
th.Name = "FileSystemTask1"
fst = CType(th.InnerObject, FileSystemTask)
fst.Operation = DTSFileSystemOperation.DeleteFile
fst.Source = "sourceFile"
fst.IsSourcePathVariable = True
Dim vr As DTSExecResult = p.Validate(Nothing, Nothing, Nothing, Nothing)
Console.WriteLine("ValidationResult = " + vr.ToString())
If vr = DTSExecResult.Success Then
Dim er As DTSExecResult = p.Execute(Nothing, Nothing, Nothing, Nothing, Nothing)
Console.WriteLine("ExecutionResult = " + er.ToString())
If er = DTSExecResult.Failure Then
If Not File.Exists("C:\Windows\Temp\" + f) Then
Console.WriteLine("Source file has been deleted by the event handler.")
End If
End If
End If
Console.Read()
End Sub
End Module
|