Oracle
 sql >> Datenbank >  >> RDS >> Oracle

So erhalten Sie eine Datenbankbenachrichtigung für die C++-Anwendung

Ein Ansatz ist die Verwendung von Oracle's Advanced Queuing . Zu diesem Zweck müssen Sie eine Warteschlange (und eine Warteschlangentabelle) einrichten und eine PL/SQL-Prozedur schreiben, die auf die nächste Nachricht in der Warteschlange wartet.

Die C++-Seite ruft dann die PL/SQL-Prozedur auf, die zurückkehrt, wenn das nächste Ereignis aufgetreten ist.

Auf der Oracle-Seite müssen Sie DBMS_SCHEDULER oder eine ähnliche Einrichtung zum Erstellen des Ereignisses , d. h. zum richtigen Zeitpunkt eine neue Nachricht in die Warteschlange einzufügen.

Es ist immer noch ein Umfrageansatz. Es gibt jedoch absolut keine Aktivität zwischen zwei Ereignissen.

Aktualisierung:

Hier ist ein Beispielcode.

Initiale Einrichtung der Warteschlange (die Nachricht enthält einen numerischen und einen Textwert):

grant AQ_ADMINISTRATOR_ROLE to appuser;
grant EXECUTE ON DBMS_AQ to appuser;
grant EXECUTE ON DBMS_AQ to appuser;


CREATE TYPE sample_payload_type AS OBJECT
(
  cmd  VARCHAR2(20),
  id   NUMBER
);


BEGIN
  DBMS_AQADM.CREATE_QUEUE_TABLE (
    queue_table        => 'sample_queue_table',
    queue_payload_type => 'sample_payload_type',
    sort_list          => 'ENQ_TIME',
    compatible         => '10.0'
  );
END;
/

BEGIN
  DBMS_AQADM.CREATE_QUEUE (
    queue_name         => 'sample_queue',
    queue_table        => 'sample_queue_table'
  );

  DBMS_AQADM.START_QUEUE (
    queue_name         => 'sample_queue'
  );
END;
/

Paketkopf:

create or replace package sample_queue_pkg
as

  procedure get_next_msg(
    i_max_wait      number
   ,o_cmd      out  varchar2
   ,o_id       out  number
  );


  procedure put_msg(
    i_cmd           varchar2
   ,i_id            number
  );

end sample_queue_pkg;
/

Pakettext:

create or replace package body sample_queue_pkg
as

  procedure get_next_msg(
    i_max_wait      number
   ,o_cmd      out  varchar2
   ,o_id       out  number
  )
  is
    dequeue_options dbms_aq.dequeue_options_t;
    message_properties dbms_aq.message_properties_t;
    message_handle RAW(16);
    message sample_payload_type;

    NO_MESSAGE_RECEIVED EXCEPTION;
    PRAGMA EXCEPTION_INIT(NO_MESSAGE_RECEIVED, -25228);

  begin
    dequeue_options.wait := i_max_wait;
    DBMS_AQ.DEQUEUE (
      queue_name => 'appuser.sample_queue',
      dequeue_options => dequeue_options,
      message_properties => message_properties,
      payload => message,
      msgid => message_handle
    );

    o_cmd := message.cmd;
    o_id := message.id;

  exception
    when NO_MESSAGE_RECEIVED then
      o_cmd := null;
      o_id := null;

  end get_next_msg;


  procedure put_msg(
    i_cmd           varchar2
   ,i_id            number
  )
  is
    enqueue_options dbms_aq.enqueue_options_t;
    message_properties dbms_aq.message_properties_t;
    message_handle RAW(16);
    message sample_payload_type;
    message_id NUMBER;

  begin
    message := sample_payload_type(i_cmd, i_id);
    DBMS_AQ.ENQUEUE(
      queue_name => 'appuser.sample_queue',
      enqueue_options => enqueue_options,
      message_properties => message_properties,
    payload => message,
      msgid => message_handle
    );
  end put_msg;

end sample_queue_pkg;
/

Der Datenbankserver kann eine Nachricht mit folgendem Code senden:

sample_queue_pkg.put_msg('run_task', 8234);
commit;

Der C++-Server kann auf Nachrichten warten (und sie empfangen), indem er die gespeicherte sample_queue_pkg.get_next_msg aufruft . Der Parameter i_max_wait gibt die maximale Wartezeit in Sekunden auf die nächste Nachricht an. Wahrscheinlich möchten Sie eine Schleife implementieren, die auf die nächste Nachricht wartet und sie verarbeitet, bis sie ein Signal erhält, dass der Server dabei ist, sich zu beenden.