データベース警告(FireDAC)
コマンドの操作(FireDAC) への移動
DBMS 警告とは、データベース側の何らかのイベントについて、データベース トリガやストアド プロシージャからデータベース クライアントに通知するために送信される、データベースに関する通知や警告のことです。
警告は、名前によって識別することができ、追加の引数を含むことができます。クライアントは警告に登録しています。複数のクライアントが 1 つの警告に登録することができ、1 つのクライアントが複数の警告に登録することができます。データベース内で警告が発生すると、それが、登録したすべてのクライアントに通知されます。警告を使わなくなれば、アプリケーションはその警告から登録解除します。
典型的な警告の例には次のようなものがあります。
- テーブル データの変更。この場合、アプリケーションでは、このテーブル データを返すデータセットを最新状態に更新します。
- データが何らかの条件を満たしたときの通知。
- データのアーカイブやバックアップなど、特定のアプリケーションが特別な処理を実行するということを、他のアプリケーションに知らせる通知。
DBMS ごとに、独自に DBMS 警告が実装されています。警告メカニズムの標準はありません。
TFDEventAlerter の使用
FireDAC は、警告 API を TFDEventAlerter コンポーネントとして一元管理しています。DBMS によっては、DBMS 警告メカニズムをほとんど実装していないものがあります。各 TFDEventAlerter オブジェクトは、警告の名前を TFDEventAlerter.Names プロパティに指定し、Options.Kind プロパティに指定された 1 つのメカニズムを使用することで、複数の警告をリスンします。
FireDAC では、データベースに対して追加で非公開の接続を行い、それを使ってバックグラウンド スレッドで警告をリスンします。この追加の接続は、FireDAC によって TFDEventAlerter コンポーネントごとに自動的に作成されます。アプリケーションで複数の TFDEventAlerter オブジェクトを作成する場合には、マルチスレッド処理|プールされた接続を使ってパフォーマンスを向上することを検討してください。
イベント警告の受信を開始するには、TFDEventAlerter.Names プロパティに必要なイベントの名前を追加します。Options.Kind にイベント アラータの種類を設定します(これを空にしておくとデフォルトのアラータが使われます)。イベントが発生したときに呼び出される OnAlert イベント ハンドラを指定し、Active を True に設定するか、Register メソッドを呼び出します。イベント警告の受信を中止するには、Active を False に設定するか、Unregister を呼び出します。
OnAlert イベント ハンドラは、メイン スレッドでもバックグラウンド スレッドでも呼び出すことができます。Options.Synchronize プロパティを使用すると、それを制御できます。
- メモ: アプリケーションでは、バックグラウンド スレッド ハンドラの実行時間を最小限にするべきです。
アプリケーションで警告のタイムアウトを設定するには、Options.Timeout プロパティを指定します。指定された時間の間に警告が発生しなければ、OnTimeout イベント ハンドラが呼び出されます。
たとえば、Oracle データベースでは "DBMS_ALERT" メカニズムを、Firebird では標準のメカニズムを使って "Customers" 警告に登録するには、次のコードを使用します。
FDEventAlerter1.Names.Clear;
FDEventAlerter1.Names.Add('Customers');
case FDConnection1.RDBMSKind of
mkOracle: FDEventAlerter1.Options.Kind := 'DBMS_ALERT';
mkInterbase: FDEventAlerter1.Options.Kind := 'Events';
end;
FDEventAlerter1.Options.Synchronize := True;
FDEventAlerter1.Options.Timeout := 10000;
FDEventAlerter1.OnAlter := DoAlert;
FDEventAlerter1.OnTimeout := DoTimeout;
FDEventAlerter1.Active := True;
// …
procedure TForm1.DoAlert(ASender: TFDCustomEventAlerter;
const AEventName: String; const AArgument: Variant);
begin
if CompareText(AEventName, 'Customers') = 0 then
qryCustomers.Refresh;
end;
procedure TForm1.DoTimeout(ASender: TObject);
begin
// …
end;
Oracle のサーバー側のコードは次のようにします。
CREATE OR REPLACE TRIGGER TR_CUSTOMERS
AFTER INSERT OR UPDATE OR DELETE ON CUSTOMERS
BEGIN
SYS.DBMS_ALERT.SIGNAL('Customers', '123');
END;
Firebird では次のコードを使用します。
CREATE TRIGGER TR_CUSTOMERS FOR CUSTOMERS
ACTIVE AFTER INSERT OR UPDATE OR DELETE
BEGIN
POST_EVENT 'Customers';
END;
DBMS 警告メカニズム
先に述べたように、データベース警告の実装方法は DBMS ごとに異なります。警告メカニズムの種類は、TFDEventAlerterOptions.Kind プロパティの値で識別されます。このプロパティが空の場合には、デフォルトのメカニズムが使われます。クライアント側の機能はほとんどのメカニズムで同じであり、データベース側の機能だけが異なっています。
FireDAC ドライバがサポートしている DBMS とその警告メカニズムの一覧を以下の表に示します。
DBMS | イベント アラータの種類 | 説明 |
---|---|---|
Advantage Database | Events (*) | 標準のイベント(通知)機能が使われます。イベントを起動するには、sp_SignalEvent ストアド プロシージャを使用します。例:
sp_SignalEvent('Customers', true, 0, '123');
|
Sybase SQL Anywhere | Message(*) | MESSAGE 文の機能を使用します。イベントを起動するには、この種類の特別な形式のメッセージ _FD_$$<イベント名>[$$<引数>] を送信する必要があります。例:
MESSAGE '_FD_$$Customers$$123' |
DataSnap サーバー | Callbacks(*) | DataSnap の "重量" コールバックが使われます(詳細は「Delphi Labs: DataSnap XE - Callbacks」(Delphi ラボ: DataSnap XE - コールバック)を参照)。TFDEventAlerter.Names の内容は、次のいずれかの形式でなければなりません。
|
DB2 | DBMS_ALERT (*) | DBMS_ALERT パッケージが使われます。使用する前に、DBA が GRANT EXECUTE ON DBMS_ALERT TO <ユーザーまたはグループ> を実行しておく必要があります。イベントを起動するには、DBMS_ALERT.SIGNAL を呼び出します。例:
CALL DBMS_ALERT.SIGNAL('Customers', '123'); |
DBMS_PIPE | DBMS_PIPE パッケージが使われます。使用する前に、DBA が GRANT EXECUTE ON DBMS_PIPE TO <ユーザーまたはグループ> を実行しておく必要があります。イベントを起動するには、DBMS_PIPE.SEND_MESSAGE を呼び出します。例:
BEGIN CALL DBMS_PIPE.PACK_MESSAGE(123); CALL DBMS_PIPE.SEND_MESSAGE('Customers'); END; | |
Firebird | Events (*) | 標準の Firebird イベント通知メカニズムが使われます。イベントを起動するには、POST_EVENT <名前> 文を使用します。例:
EXECUTE BLOCK AS BEGIN POST_EVENT 'Customers'; END; |
Informix | DBMS_ALERT (*) | DBMS_ALERT パッケージが外部互換パッケージから使われます。イベントを起動するには、DBMS_ALERT.SIGNAL を呼び出します。例:
EXECUTE PROCEDURE DBMS_ALERT_SIGNAL('Customers', '123') |
InterBase | Events (*) | 標準の InterBase イベント通知メカニズムが使われます。イベントを起動するには、トリガまたはストアド プロシージャ内で POST_EVENT <名前> 文を使用します。クライアント側での起動はサポートされていません。 |
Microsoft SQL Server | QueryNotifies(*) | クエリ更新通知サービスが使われます。TFDEventAlerter.Names の内容は、次のいずれかの形式でなければなりません。
さらに、Names には以下のパラメータを指定することができます。
ALTER DATABASE <データベース名> SET ENABLE_BROKER |
MongoDB | Tail (*) |
追尾可能カーソルを指定されたキャップ コレクション上で使用して、挿入について警告をすることができます。 アラータの Names プロパティは、ターゲットのキャップ コレクションを指定するため、次の形式のいずれかを使用した、単一の値を含んでいなければなりません。
項目説明:
挿入が発生した際、OnAlert イベントのハンドラは、挿入されたドキュメントを JSON 文字列( |
Oracle | DBMS_ALERT (*) | DBMS_ALERT パッケージが使われます。使用する前に、DBA が GRANT EXECUTE ON DBMS_ALERT TO <ユーザーまたはグループ> を実行しておく必要があります。イベントを起動するには、DBMS_ALERT.SIGNAL を呼び出します。例:
BEGIN SYS.DBMS_ALERT.SIGNAL('Customers', '123'); END; |
DBMS_PIPE | DBMS_PIPE パッケージが使われます。使用する前に、DBA が GRANT EXECUTE ON DBMS_PIPE TO <ユーザーまたはグループ> を実行しておく必要があります。イベントを起動するには、DBMS_PIPE.SEND_MESSAGE を呼び出します。例:
BEGIN SYS.DBMS_PIPE.PACK_MESSAGE(123); SYS.DBMS_PIPE.SEND_MESSAGE('Customers'); END; | |
QueryNotifies | CQN(連続問合せ通知)機能は、データ変更通知機能を Oracle で実装したものです。詳細は、「Oracle CQN」や「Continuous Query Notification(連続問合せ通知)」を参照。 | |
PostgreSQL | Notifies(*) | 標準のイベント通知メカニズムが使われます。イベントを起動するには、NOTIFY <名前> 文を使用します。PostgreSQL 9.0 では、ペイロード引数をサポートしており、NOTIFY <名前> [, <paylod>] を使用します。例:
NOTIFY Customers |
SQLite | Events (*) | POST_EVENT カスタム関数が使われます。イベントを起動するには、POST_EVENT(<名前>, [arg1 [,arg2 [,arg3 [,arg4]]]]) を使用します。例:
SELECT POST_EVENT('Customers', 123) |
- メモ: アスタリスクは、デフォルトのイベント アラータの種類であることを示しています。
関連項目
- マルチスレッド処理
- TFDEventAlerter サンプル アプリケーション