Oracle 如何向C++;应用 我们正在开发一个基于时间的事件处理的C++服务器。例如,如果特定的用户已经配置了特定的任务,该任务必须在特定的时间被处理,那么事件或通知需要从数据库发送到C++服务器,以启动任务。TIMEME配置存储在数据库中,C++服务器不应该在一个时间间隔对数据库进行轮询,但是在配置的TimeM.中,应该从数据库通知事件。

Oracle 如何向C++;应用 我们正在开发一个基于时间的事件处理的C++服务器。例如,如果特定的用户已经配置了特定的任务,该任务必须在特定的时间被处理,那么事件或通知需要从数据库发送到C++服务器,以启动任务。TIMEME配置存储在数据库中,C++服务器不应该在一个时间间隔对数据库进行轮询,但是在配置的TimeM.中,应该从数据库通知事件。,oracle,visual-c++,oracle10g,oracle11g,oledb,Oracle,Visual C++,Oracle10g,Oracle11g,Oledb,我们使用odatabase和odynaset库来连接和访问oracle数据库11g 请您提供上述问题的解决方案。一种方法是使用。为此,您需要设置一个队列(和一个队列表),并编写一个PL/SQL过程来等待队列中的下一条消息 C++侧调用PL/SQL过程,在下一个事件发生时返回。 在Oracle方面,您需要使用或类似的工具来创建事件,即在适当的时间将新消息插入队列 这仍然是一种投票方式。然而,两个事件之间绝对没有活动 更新: 下面是一些示例代码 队列的初始设置(消息包含数字和文本值): 包头: c

我们使用odatabase和odynaset库来连接和访问oracle数据库11g

请您提供上述问题的解决方案。

一种方法是使用。为此,您需要设置一个队列(和一个队列表),并编写一个PL/SQL过程来等待队列中的下一条消息

C++侧调用PL/SQL过程,在下一个事件发生时返回。 在Oracle方面,您需要使用或类似的工具来创建事件,即在适当的时间将新消息插入队列

这仍然是一种投票方式。然而,两个事件之间绝对没有活动

更新:

下面是一些示例代码

队列的初始设置(消息包含数字和文本值):

包头:

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;
/
包体:

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;
/
数据库服务器可以使用以下代码发送消息:

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

C++服务器可以等待消息(并接收它们)调用存储的<代码> SAMPLE、QueQueLypkg.GETJNEXTHMSG< <代码>。参数

i_max_wait
指定等待下一条消息的最长时间(以秒为单位)。您可能希望实现一个循环,等待下一条消息并对其进行处理,直到收到服务器即将退出的信号。

一种方法是使用。为此,您需要设置一个队列(和一个队列表),并编写一个PL/SQL过程来等待队列中的下一条消息

C++侧调用PL/SQL过程,在下一个事件发生时返回。 在Oracle方面,您需要使用或类似的工具来创建事件,即在适当的时间将新消息插入队列

这仍然是一种投票方式。然而,两个事件之间绝对没有活动

更新:

下面是一些示例代码

队列的初始设置(消息包含数字和文本值):

包头:

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;
/
包体:

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;
/
数据库服务器可以使用以下代码发送消息:

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

C++服务器可以等待消息(并接收它们)调用存储的<代码> SAMPLE、QueQueLypkg.GETJNEXTHMSG< <代码>。参数

i_max_wait
指定等待下一条消息的最长时间(以秒为单位)。您可能希望实现一个循环,等待下一条消息并对其进行处理,直到收到服务器即将退出的信号。

一种方法是使用dbms\u管道或dbms\u警报。IE从C++服务器会话连接到DB(PRO C),调用DMSMSYPLATE/Ac告警,它将阻止到DB,在另一个会话中,数据将从C++服务器读取的管道发送,然后处理。例如,如果您想发送一个简单的“立即运行”,那么dbms_警报就可以了

例如:

SQL> declare
  2    v_name  varchar2(200);
  3    v_msg   varchar2(200);
  4    v_sts   number; -- 0 = alert occured, 1 = timeout
  5  begin
  6    dbms_alert.register('RUN_PROGRAM_A');
  7    dbms_alert.register('RUN_PROGRAM_B');
  8
  9    loop
 10      dbms_alert.waitany(v_name,
 11                         v_msg,
 12                         v_sts,
 13                         dbms_alert.maxwait);
 14
 15      if (v_sts = 0)
 16      then
 17        dbms_output.put_line('i got alert: ' ||v_name);
 18        dbms_output.put_line(' with assoc message: ' ||v_msg);
 19      end if;
 20      if (v_name  = 'RUN_PROGRAM_B')
 21      then
 22        exit;
 23      end if;
 24    end loop;
 25  end;
 26  /
i got alert: RUN_PROGRAM_A
with assoc message: whatever you want to transmit.
i got alert: RUN_PROGRAM_A
with assoc message: whatever you want to transmit.
i got alert: RUN_PROGRAM_B
with assoc message: whatever you want to transmit.

PL/SQL procedure successfully completed.
如果db控制会话发布了此命令:

SQL> exec dbms_alert.signal('RUN_PROGRAM_A', 'whatever you want to transmit.');

PL/SQL procedure successfully completed.

SQL> commit;

Commit complete.

SQL> exec dbms_alert.signal('RUN_PROGRAM_A', 'whatever you want to transmit.');

PL/SQL procedure successfully completed.

SQL> commit;

Commit complete.

SQL> exec dbms_alert.signal('RUN_PROGRAM_B', 'whatever you want to transmit.');

PL/SQL procedure successfully completed.

SQL> commit;

Commit complete.

SQL>

另一种方法是调度程序方法(
dbms\u queue
),这是一种消息队列方法,在这种方法中,您将对队列表进行轮询(出列),并在消息到达时执行某些操作。

一种方法是使用dbms\u管道或dbms\u警报。IE从C++服务器会话连接到DB(PRO C),调用DMSMSYPLATE/Ac告警,它将阻止到DB,在另一个会话中,数据将从C++服务器读取的管道发送,然后处理。例如,如果您想发送一个简单的“立即运行”,那么dbms_警报就可以了

例如:

SQL> declare
  2    v_name  varchar2(200);
  3    v_msg   varchar2(200);
  4    v_sts   number; -- 0 = alert occured, 1 = timeout
  5  begin
  6    dbms_alert.register('RUN_PROGRAM_A');
  7    dbms_alert.register('RUN_PROGRAM_B');
  8
  9    loop
 10      dbms_alert.waitany(v_name,
 11                         v_msg,
 12                         v_sts,
 13                         dbms_alert.maxwait);
 14
 15      if (v_sts = 0)
 16      then
 17        dbms_output.put_line('i got alert: ' ||v_name);
 18        dbms_output.put_line(' with assoc message: ' ||v_msg);
 19      end if;
 20      if (v_name  = 'RUN_PROGRAM_B')
 21      then
 22        exit;
 23      end if;
 24    end loop;
 25  end;
 26  /
i got alert: RUN_PROGRAM_A
with assoc message: whatever you want to transmit.
i got alert: RUN_PROGRAM_A
with assoc message: whatever you want to transmit.
i got alert: RUN_PROGRAM_B
with assoc message: whatever you want to transmit.

PL/SQL procedure successfully completed.
如果db控制会话发布了此命令:

SQL> exec dbms_alert.signal('RUN_PROGRAM_A', 'whatever you want to transmit.');

PL/SQL procedure successfully completed.

SQL> commit;

Commit complete.

SQL> exec dbms_alert.signal('RUN_PROGRAM_A', 'whatever you want to transmit.');

PL/SQL procedure successfully completed.

SQL> commit;

Commit complete.

SQL> exec dbms_alert.signal('RUN_PROGRAM_B', 'whatever you want to transmit.');

PL/SQL procedure successfully completed.

SQL> commit;

Commit complete.

SQL>

另一种方法是调度器方法(/Cudio>),它是一种消息队列方法,在其中,你将对队列表进行轮询(DELUBLE),当消息到达时,它会做一些事情。

OODATABORE和OORDeNETScript,你是指OLE C++类库的Oracle对象?谢谢快速响应。是的,OLE C++数据库通过OrdBoo+OrDeDeCub库,你是指OLE C++类库的Oracle对象吗?谢谢快速响应。是的,它的OLE C++库是CeraTyQueLeEx表,并创建队列,就像正常的SQL查询一样?如“EXECUTE DBMS_AQADM.CREATE_QUEUE_TABLE(CREATE_QUEUE_TABLE=>'sample_QUEUE_TABLE',QUEUE_payload_type=>'sample_payload_type',sort_list=>'ENQ_TIME',compatible=>'10.0');”如果不是这样做的话,请使用hlp me out。是的,您也可以使用EXECUTE(或EXEC)来代替BEGIN/END,这是将行的其余部分包装成开始/结束对的捷径。我建议阅读以了解更多关于队列和队列表等概念的信息。我像这样执行quetable“EXECUTE Proc_GetTypeCS.CREATE_queue_TABLE”(queue_TABLE=>“queue_message_TABLE”,queue_payload_type=>“queue_message_type”);但其抛出错误“'PROC_GETTYPECS'引用超出范围"但该过程已成功创建。您无法用Proc_GetTypeCS替换DBMS_AQADM。DBMS_AQADM是用于高级队列的Oracle软件包。它包含创建和管理队列的相关过程。您确实需要研究Oracle文档。上面示例中的Hi-codo u发布排队不是自动发生的,对吗,我需要它自动发生,在这种情况下我该怎么做,请帮助我。创建队列表和创建队列是像普通sql查询一样执行的吗?像这样“执行DBMS\u AQADM.CREATE\u QUEUE\u TABLE(CREA