データベース警告(FireDAC)

提供: Appmethod Topics
移動先: 案内検索

コマンドの操作(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 イベント ハンドラを指定し、ActiveTrue に設定するか、Register メソッドを呼び出します。イベント警告の受信を中止するには、ActiveFalse に設定するか、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');

メモ: sp_SignalEvent を呼び出せるのはストアド プロシージャまたはトリガからだけです。SQL コマンドから直接呼び出すことはできません。
Sybase SQL Anywhere Message(*) MESSAGE 文の機能を使用します。イベントを起動するには、この種類の特別な形式のメッセージ _FD_$$<イベント名>[$$<引数>] を送信する必要があります。例:

MESSAGE '_FD_$$Customers$$123'

DataSnap Server Callbacks(*) DataSnap の "重量" コールバックが使われます(詳細は「Object Pascal Labs: DataSnap XE - Callbacks」(Object Pascal ラボ: DataSnap XE - コールバック)を参照)。TFDEventAlerter.Names の内容は、次のいずれかの形式でなければなりません。
  • <チャネル名>. FireDAC は、指定したチャネルにコールバックを登録します。TDSAdminClient.BroadcastToChannel を使用すると、指定したチャネルに登録されたすべての TADEventAlerter にイベントをブロードキャストすることができます。
  • <チャネル名>=<コールバック名>. FireDAC は、指定したチャネルに指定した名前でコールバックを登録します。イベントを起動する方法は、上記を参照。
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 Query Notification(*) クエリ更新通知サービスが使われます。TFDEventAlerter.Names の内容は、次のいずれかの形式でなければなりません。
  • CHANGE<インデックス>=<メッセージ>;<SELECT クエリ>. SELECT クエリから返されたデータが更新されるとイベントが発生し、<メッセージ> がイベント名として返されます。イベントを発生させるには、取得されたデータに対する UPDATE 文を実行しなければなりません。
  • <メッセージ>. FireDAC は _FD_EVENTS テーブルを作成します。NAME が <メッセージ> である行の VALUE が更新されるとイベントが発生します。イベントを発生させるには、UPDATE 文を実行しなければなりません。

さらに、Names には以下のパラメータを指定することができます。

  • SERVICE=<名前>. 使用するサービスの名前です。"?" は、一意の名前の付いたサービスを作成し、使い終わったら削除することを意味します。
  • QUEUE=<名前>. 使用するメッセージ キューの名前です。"?" は、一意の名前の付いたキューを作成し、使い終わったら削除することを意味します。
メモ: クエリ通知を有効にするには、以下のコマンドを実行します。

ALTER DATABASE <データベース名> SET ENABLE_BROKER

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;

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)

メモ: アスタリスクは、デフォルトのイベント アラータの種類であることを示しています。

FireDAC\Samples\Comp Layer\TFDEventAlerter\Main FireDAC デモを参照してください。

関連項目