Datenbankwarnungen (FireDAC)

Aus RAD Studio
Wechseln zu: Navigation, Suche

Nach oben zu Arbeiten mit Anweisungen (FireDAC)


Die DBMS-Warnung bezieht sich auf eine Datenbankbenachrichtigung oder eine Warnung, die von einem Datenbank-Trigger oder einer gespeicherten Prozedur mit dem Zweck gesendet wird, einen Datenbank-Client über Ereignisse auf der Datenbankseite zu benachrichtigen.

Eine Warnung ist durch einen Namen gekennzeichnet und kann weitere Argumente enthalten. Die Clients werden für Warnungen registriert. Mehrere Clients können für eine einzelne Warnung registriert sein, und ein Client kann für mehrere Warnungen registriert sein. Wenn eine Warnung in einer Datenbank signalisiert wird, werden alle registrierten Clients darüber informiert. Wenn eine Warnung nicht mehr verwendet wird, hebt die Anwendung die Registrierung dieser Warnung auf.

Typische Beispiele für Warnungen sind:

  • Das Ändern einer Tabelle. In diesem Fall aktualisiert die Anwendung eine Datenmenge, die diese Tabellendaten zurückgibt.
  • Eine Benachrichtigung darüber, dass eine Bedingung in den Daten erfüllt wurde.
  • Eine Benachrichtigung, die an andere Anwendungen gesendet wurde, dass eine bestimmte Anwendung besondere Aufgaben durchführt, wie z. B. Archivierung oder Sicherung von Daten.

Jedes DBMS implementiert DBMS-Warnungen in einer eigenen Art und Weise. Für den Warnungsmechanismus gibt es keine Standardverfahren.

Verwenden von TFDEventAlerter

FireDAC stellt mit der Komponente TFDEventAlerter eine einheitliche Warnungs-API bereit. Bestimmte DBMSs implementieren eventuell einige DBMS-Warnungsmechanismen. Jedes TFDEventAlerter-Objekt empfängt mehrere Warnungen, indem deren Namen in der Eigenschaft TFDEventAlerter.Names angegeben werden und ein in der Eigenschaft Options.Kind festgelegter Mechanismus verwendet wird.

FireDAC empfängt Warnungen in einem Hintergrund-Thread über eine zusätzliche private Verbindung zu der Datenbank. Die zusätzliche Verbindung wird von FireDAC automatisch für jede TFDEventAlerter-Komponente erstellt. Wenn die Anwendung mehrere TFDEventAlerter-Objekte erstellt, sollten Sie Pool-Verbindungen zur Verbesserung der Leistung verwenden.

Geben Sie in der Eigenschaft TFDEventAlerter.Names die gewünschten Ereignisnamen ein, um den Empfang von Ereignisbenachrichtigungen zu starten. Setzen Sie die Eigenschaft Options.Kind auf den Typ der Ereigniswarnung, oder lassen Sie sie leer, um die Vorgabe zu verwenden. Geben Sie die Ereignisbehandlungsroutine OnAlert an, die beim Auftreten eines Ereignisses ausgelöst wird, und setzen Sie Active auf True, oder rufen Sie die Methode Register auf. Setzen Sie Active auf False oder rufen Sie Unregister auf, um den Empfang von Ereignisbenachrichtigungen zu beenden.

Die Ereignisbehandlungsroutine OnAlert kann im Kontext des Haupt- oder des Hintergrund-Threads aufgerufen werden. Mit der Eigenschaft Options.Synchronize können Sie dies steuern.

Hinweis: Die Anwendung sollte die Laufzeit der Behandlungsroutine für Hintergrund-Threads minimieren.

Die Anwendung legt durch Setzen der Eigenschaft Options.Timeout Zeitlimits für Warnungen fest. Wenn in einer bestimmten Zeitspanne keine Warnungen auftreten, wird die Ereignisbehandlungsroutine OnTimeout aufgerufen.

Um beispielsweise eine Registrierung für die Warnung "Customers" mit dem "DBMS_ALERT"-Mechanismus für eine Oracle-Datenbank und dem Standardmechanismus von Firebird vorzunehmen, verwenden Sie den folgenden Code:


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;

Und den serverseitigen Code für Oracle:

CREATE OR REPLACE TRIGGER TR_CUSTOMERS
AFTER INSERT OR UPDATE OR DELETE ON CUSTOMERS
BEGIN
  SYS.DBMS_ALERT.SIGNAL('Customers', '123');
END;

Verwenden Sie für Firebird den folgenden Code:

CREATE TRIGGER TR_CUSTOMERS FOR CUSTOMERS
ACTIVE AFTER INSERT OR UPDATE OR DELETE
BEGIN
  POST_EVENT 'Customers';
END;

DBMS-Warnungsmechanismus

Wie bereits weiter oben erwähnt, implementiert jedes DBMS Datenbankwarnungen in einer eigenen Art und Weise. Der Typ des Warnungsmechanismus wird im Eigenschaftswert TFDEventAlerterOptions.Kind angegeben. Wenn diese Eigenschaft leer ist, wird der Standardmechanismus verwendet. Die clientseitige Funktionalität ist bei den meisten Mechanismen gleich, nur die Funktionalität auf der Datenbankseite ist unterschiedlich.

Die folgende Tabelle enthält die DBMSs und die jeweiligen, von den FireDAC-Treibern unterstützten Warnungsmechanismen:

DBMS Typ der Ereigniswarnung Beschreibung
Advantage Database Events (*) Die Standardereignisfunktionalität (Benachrichtigungen) wird verwendet. Mit der gespeicherten Prozedur sp_SignalEvent können Sie ein Ereignis initiieren. Zum Beispiel:

sp_SignalEvent('Customers', true, 0, '123');

Hinweis: sp_SignalEvent kann nur aus einer gespeicherten Prozedur oder einem Trigger aufgerufen werden. Es kann nicht direkt aus der SQL-Anweisung aufgerufen werden.
Sybase SQL Anywhere Message (*) Die MESSAGE-Anweisungsfunktionalität wird verwendet. Um ein Ereignis zu initiieren, muss eine besonders formatierte Nachricht in der Form: _FD_$$<Ereignisname>[$$<Argument>] gesendet werden. Zum Beispiel:

MESSAGE '_FD_$$Customers$$123'

DataSnap-Server Callbacks (*) Die "Heavyweight"-Callbacks von DataSnap werden verwendet (weitere Informationen finden Sie unter Delphi Labs: DataSnap XE - Callbacks). Der Inhalt von TFDEventAlerter.Names muss in einem der folgenden Formate vorliegen:
  • <Kanalname>. FireDAC registriert eine Callback-Funktion für den angegebenen Kanal. Mit TDSAdminClient.BroadcastToChannel senden Sie ein Ereignis an alle TFDEventAlerter-Komponenten, die für den angegebenen Kanal registriert sind.
  • <Kanalname>=<Callback-Name>. FireDAC registriert eine Callback-Funktion mit den angegebenen Namen für den angegebenen Kanal. Informationen zum Initiieren eines Ereignisses finden Sie oben.
DB2 DBMS_ALERT (*) Das DBMS_ALERT-Paket wird verwendet. Vor dessen Verwendung muss ein Datenbankadministrator GRANT EXECUTE ON DBMS_ALERT TO <Benutzer oder Gruppe> ausführen. Verwenden Sie zum Initiieren eines Ereignisses den Aufruf DBMS_ALERT.SIGNAL. Zum Beispiel:

CALL DBMS_ALERT.SIGNAL('Customers', '123');

DBMS_PIPE Das DBMS_PIPE-Paket wird verwendet. Vor dessen Verwendung muss ein Datenbankadministrator GRANT EXECUTE ON DBMS_PIPE TO <Benutzer oder Gruppe> ausführen. Verwenden Sie zum Initiieren eines Ereignisses den Aufruf DBMS_PIPE.SEND_MESSAGE. Zum Beispiel:

BEGIN CALL DBMS_PIPE.PACK_MESSAGE(123); CALL DBMS_PIPE.SEND_MESSAGE('Customers'); END;

Firebird Events (*) Der Standardmechanismus von Firebird für Ereignisbenachrichtigungen wird verwendet. Verwenden Sie zum Initiieren eines Ereignisses die Anweisung POST_EVENT <Name>. Zum Beispiel:

EXECUTE BLOCK AS BEGIN POST_EVENT 'Customers'; END;

Informix DBMS_ALERT (*) Das DBMS_ALERT-Paket wird aus dem externen Kompatibilitätspaket verwendet. Verwenden Sie zum Initiieren eines Ereignisses den Aufruf DBMS_ALERT_SIGNAL. Zum Beispiel:

EXECUTE PROCEDURE DBMS_ALERT_SIGNAL('Customers', '123')

InterBase Events (*) Der Standardmechanismus von InterBase für Ereignisbenachrichtigungen wird verwendet. Verwenden Sie zum Initiieren eines Ereignisses die Anweisung POST_EVENT <Name> aus einem Trigger oder einer gespeicherten Prozedur. Die clientseitige Initiierung wird nicht unterstützt.
Microsoft SQL-Server QueryNotifies (*) Der Dienst "Query Update Notification" wird verwendet. Der Inhalt von TFDEventAlerter.Names muss in einem der folgenden Formate vorliegen:
  • CHANGE<Index>=<Meldung>;<SELECT-Abfrage>. Das Ereignis wird ausgelöst, wenn die von der SELECT-Abfrage zurückgegebenen Daten aktualisiert werden und die <Meldung> als Ereignisname zurückgegeben wird. Um ein Ereignis auszulösen, muss eine UPDATE-Anweisung für die ausgewählten Daten ausgeführt werden.
  • <Meldung>. FireDAC erstellt die Tabelle _FD_EVENTS. Das Ereignis wird ausgelöst, wenn VALUE der Zeile NAME=<Meldung> aktualisiert wird. Um ein Ereignis auszulösen, muss eine UPDATE-Anweisung ausgeführt werden.

Des Weiteren können die folgenden Parameter in "Names" angegeben werden:

  • SERVICE=<Name>. Der Name des zu verwendenden Dienstes. '?' bedeutet, dass ein eindeutig benannter Dienst erstellt und nach der Verwendung wieder gelöscht wird.
  • QUEUE=<Name>. Der Name der zu verwendenden Meldungswarteschlange. '?' bedeutet, dass eine eindeutig benannte Warteschlange erstellt und nach der Verwendung wieder gelöscht wird.
Hinweis: Um die Abfragebenachrichtigung zu aktivieren, führen Sie die folgende Anweisung aus:

ALTER DATABASE <Name Ihrer DB> SET ENABLE_BROKER

MongoDB Tail (*)

Verwendet zum Warnen über Einfügungen einen sogenannten tailable Cursor (EN) auf einer gegebenen größenbeschränkten Dokumentensammlung (EN) (capped collection).

Um die größenbeschränkte Ziel-Dokumentensammlung anzugeben, muss die Eigenschaft Names der Warnung einen einzigen Wert enthalten und eines der folgenden Formate verwenden:

  • <database>.<collection>
  • <database>.<collection>=<size>
  • <collection>
  • <collection>=<size>

Wobei Folgendes gilt:

  • <database> ist der Name der Datenbank, die die größenbeschränkte Ziel-Dokumentensammlung enthält. Der Standarddatenbankname ist "test".
  • <collection> ist der Name der größenbeschränkten Ziel-Dokumentensammlung.
  • Wenn die Ziel-Dokumentensammlung nicht existiert, erstellt FireDAC eine neue größenbeschränkte Dokumentensammlung mit dem angegebenen Datenbanknamen, Sammlungsnamen und Dokumentenanzahl (<size>). Die Standardanzahl ist 1000 (Dokumente).

Wenn eine Einfügung vorkommt, erhält Ihre Behandlungsroutine für das Ereignis OnAlert das eingefügte Dokument als JSON-String (AArgument). AEventName ist der Wert des Feldes "Name" des eingefügten Dokuments.

Oracle DBMS_ALERT (*) Das DBMS_ALERT-Paket wird verwendet. Vor dessen Verwendung muss ein Datenbankadministrator GRANT EXECUTE ON DBMS_ALERT TO <Benutzer oder Gruppe> ausführen. Verwenden Sie zum Initiieren eines Ereignisses den Aufruf DBMS_ALERT.SIGNAL. Zum Beispiel:

BEGIN SYS.DBMS_ALERT.SIGNAL('Customers', '123'); END;

DBMS_PIPE Das DBMS_PIPE-Paket wird verwendet. Vor dessen Verwendung muss ein Datenbankadministrator GRANT EXECUTE ON DBMS_PIPE TO <Benutzer oder Gruppe> ausführen. Verwenden Sie zum Initiieren eines Ereignisses den Aufruf DBMS_PIPE.SEND_MESSAGE. Zum Beispiel:

BEGIN SYS.DBMS_PIPE.PACK_MESSAGE(123); SYS.DBMS_PIPE.SEND_MESSAGE('Customers'); END;

QueryNotifies Die Funktion "Continuous Query Notification (CQN)" ist eine Oracle-Implementierung der Funktion "Benachrichtigungen über Datenänderungen". Weitere Informationen finden Sie unter Oracle-CQN und Continuous Query Notification (EN).
PostgreSQL Notifies (*) Der Standardmechanismus für die Ereignisbenachrichtigung wird verwendet. Verwenden Sie zum Initiieren eines Ereignisses die Anweisung NOTIFY <Name>. PostgreSQL 9.0 unterstützt Nutzdatenargumente, verwenden Sie NOTIFY <Name> [, <paylod>]. Zum Beispiel:

NOTIFY Customers

SQLite Events (*) Die benutzerdefinierte Funktion POST_EVENT wird verwendet. Verwenden Sie zum Initiieren eines Ereignisses POST_EVENT(<Name>, [Arg1 [,Arg2 [,Arg3 [,Arg4]]]]). Zum Beispiel:

SELECT POST_EVENT('Customers', 123)

Hinweis: Der Standardtyp der Ereigniswarnung ist mit einem Sternchen gekennzeichnet.

Siehe auch