建立队列表
队列表是队列的集合,代码如下:
创建下行和上行队列表:
Sql代码
execdbms_aqadm.create_queue_table(queue_table=>'sms_mt_tab', queue_payload_type=>'mt_struc');exec dbms_aqadm.create_queue_table(queue_table=>'sms_mt_tab', queue_payload_type=>'mt_struc');
默认:只有一个接收者
具体参数如下:
Sql代码
SQL>descdbms_aqadm.create_queue_table
Parameter Type ModeDefault?
------------------ -------------- ---- --------
QUEUE_TABLE VARCHAR2IN
QUEUE_PAYLOAD_TYPE VARCHAR2IN
STORAGE_CLAUSE VARCHAR2INY
SORT_LIST VARCHAR2INY
MULTIPLE_CONSUMERS BOOLEANINY
MESSAGE_GROUPING BINARY_INTEGERINY
COMMENT VARCHAR2INY
AUTO_COMMIT BOOLEANINY
PRIMARY_INSTANCE BINARY_INTEGERINY
SECONDARY_INSTANCE BINARY_INTEGERINY
COMPATIBLE VARCHAR2INY
NON_REPUDIATION BINARY_INTEGERINY
SECURE BOOLEANINYSQL> desc dbms_aqadm.create_queue_table
Parameter Type Mode Default?
------------------ -------------- ---- --------
QUEUE_TABLE VARCHAR2 IN
QUEUE_PAYLOAD_TYPE VARCHAR2 IN
STORAGE_CLAUSE VARCHAR2 IN Y
SORT_LIST VARCHAR2 IN Y
MULTIPLE_CONSUMERS BOOLEAN IN Y
MESSAGE_GROUPING BINARY_INTEGER IN Y
COMMENT VARCHAR2 IN Y
AUTO_COMMIT BOOLEAN IN Y
PRIMARY_INSTANCE BINARY_INTEGER IN Y
SECONDARY_INSTANCE BINARY_INTEGER IN Y
COMPATIBLE VARCHAR2 IN Y
NON_REPUDIATION BINARY_INTEGER IN Y
SECURE BOOLEAN IN Y
参考dbms_aqadm.create_queue_table
1.存储参数storage_clause 可以是 MAXTRANS,LOB等
2.sort_list 可以是PRIORITY,enq_time这2个参数或者其中一个。具体可以察看对应的 队列表的数据结构。例如下面的例子
--创建队列表,‘sms_aq_tab’ 队列表名,' sms_aq_tab '队列对象名(充当消息体的对象名称),以下同
Sql代码
dbms_aqadm.create_queue_table('WDZAQTABLE','WDZAQMSG');dbms_aqadm.create_queue_table('WDZAQTABLE','WDZAQMSG');
--创建具有排序功能的队列表
Sql代码
dbms_aqadm.create_queue_table('WDZSQRTAQTABLE','WDZAQMSG',sort_list =>'PRIORITY,enq_time');dbms_aqadm.create_queue_table('WDZSQRTAQTABLE','WDZAQMSG',sort_list => 'PRIORITY,enq_time');3。消息分组参数 message_grouping 可以是 NONE,或 TRANSACTIONAL
Sql代码
-- message grouping
dbms_aqadm.TRANSACTIONAL CONSTANT BINARY_INTEGER := 1;
dbms_aqadm.NONE CONSTANT BINARY_INTEGER := 0;-- message grouping
dbms_aqadm.TRANSACTIONAL CONSTANT BINARY_INTEGER := 1;
dbms_aqadm.NONE CONSTANT BINARY_INTEGER := 0;后者表示一个与事务相关的消息分成1组,在提取消息的时候可以当成一组相关消息来提取。例如:
Sql代码
--创建带带分组功能的消息队列表
dbms_aqadm.create_queue_table('WDZGROUPAQTABLE','WDZAQMSG',
sort_list =>'PRIORITY,enq_time',
message_grouping =>dbms_aqadm.TRANSACTIONAL/*dbms_aqadm.NONE*/ );--创建带带分组功能的消息队列表
dbms_aqadm.create_queue_table('WDZGROUPAQTABLE','WDZAQMSG',
sort_list => 'PRIORITY,enq_time',
message_grouping =>dbms_aqadm.TRANSACTIONAL/*dbms_aqadm.NONE*/ );
4.multiple_consumers表示消息接受者是否为多个用户。默认是只有1个接收者。如果要多个用户可以接受消息,需要设置=true
Sql代码
--创建多个接收者的消息队列表
dbms_aqadm.create_queue_table('WDZMUTIAQTABLE','WDZAQMSG',sort_list =>'PRIORITY,enq_time',
message_grouping =>dbms_aqadm.TRANSACTIONAL/*dbms_aqadm.NONE*/
,multiple_consumers =>true);--创建多个接收者的消息队列表
dbms_aqadm.create_queue_table('WDZMUTIAQTABLE','WDZAQMSG',sort_list => 'PRIORITY,enq_time',
message_grouping =>dbms_aqadm.TRANSACTIONAL/*dbms_aqadm.NONE*/
,multiple_consumers => true);
4.2删除队列表
Sql代码
Execdbms_aqadm.drop_queue_table(queue_table =>'sms_mt_tab');
Execdbms_aqadm.drop_queue_table(queue_table =>'sms_mo_tab');Exec dbms_aqadm.drop_queue_table(queue_table => 'sms_mt_tab');
Exec dbms_aqadm.drop_queue_table(queue_table => 'sms_mo_tab');
4.3建立队列
建立队列代码如下:
Sql代码
execdbms_aqadm.create_queue(queue_name=>'sms_mt_queue', queue_table=>'sms_mt_tab');
execdbms_aqadm.create_queue(queue_name=>'sms_mt_queue_exception', queue_table=>'sms_mt_tab',queue_type=>dbms_aqadm.EXCEPTION_QUEUE);
execdbms_aqadm.create_queue(queue_name=>'sms_mt_queue_backup', queue_table=>'sms_mt_tab');exec dbms_aqadm.create_queue(queue_name=>'sms_mt_queue', queue_table=>'sms_mt_tab');
exec dbms_aqadm.create_queue(queue_name=>'sms_mt_queue_exception', queue_table=>'sms_mt_tab',queue_type=>dbms_aqadm.EXCEPTION_QUEUE);
exec dbms_aqadm.create_queue(queue_name=>'sms_mt_queue_backup', queue_table=>'sms_mt_tab');
参数含义:
Sql代码
--参考 dbms_aqadm.create_queue
--创建队列, sms_mt_queue为队列的名称,' sms_mt_tab ' 队列表名
dbms_aqadm.create_queue('WDZQUEUE','WDZAQTABLE',queue_type => dbms_aqadm.NORMAL_QUEUE);
--参数queue_type 表示队列是否为正常队列还是异常队列,
--参数值为dbms_aqadm.NORMAL_QUEUE 或者dbms_aqadm.EXCEPTION_QUEUE
--创建多用户队列, 'WDZQUEUE' 为队列的名称,'WDZAQTABLE' 队列表名
dbms_aqadm.create_queue('WDZMUTIQUEUE','WDZMUTIAQTABLE',
queue_type => dbms_aqadm.NORMAL_QUEUE);
--创建分组队列, 'WDZGROUPQUEUE' 为队列的名称,'WDZAQTABLE' 队列表名
dbms_aqadm.create_queue('WDZGROUPQUEUE','WDZAQTABLE',
queue_type => dbms_aqadm.NORMAL_QUEUE);--参考 dbms_aqadm.create_queue
--创建队列, sms_mt_queue为队列的名称,' sms_mt_tab ' 队列表名
dbms_aqadm.create_queue('WDZQUEUE','WDZAQTABLE',queue_type => dbms_aqadm.NORMAL_QUEUE);
--参数queue_type 表示队列是否为正常队列还是异常队列,
--参数值为dbms_aqadm.NORMAL_QUEUE 或者dbms_aqadm.EXCEPTION_QUEUE
--创建多用户队列, 'WDZQUEUE' 为队列的名称,'WDZAQTABLE' 队列表名
dbms_aqadm.create_queue('WDZMUTIQUEUE','WDZMUTIAQTABLE',
queue_type => dbms_aqadm.NORMAL_QUEUE);
--创建分组队列, 'WDZGROUPQUEUE' 为队列的名称,'WDZAQTABLE' 队列表名
dbms_aqadm.create_queue('WDZGROUPQUEUE', 'WDZAQTABLE',
queue_type => dbms_aqadm.NORMAL_QUEUE);
4.4删除队列
代码如下:
Sql代码
Execdbms_aqadm.drop_queue('sms_mt_queue');Exec dbms_aqadm.drop_queue('sms_mt_queue');
4.5队列参数调整
A 创建非持久队列
非持久队列 顾名思义就是没有永久保存到数据的队列,队列只存在于系统的内存中。
参考 dbms_aqadm.create_np_queue
Sql代码
dbms_aqadm. create_np_queue ('sms_mt_queue', multiple_consumers=>false);dbms_aqadm. create_np_queue ('sms_mt_queue', multiple_consumers=>false);
B 启动一个队列,' sms_mt_queue ' 为队列的名称
Sql代码
dbms_aqadm.start_queue('sms_mt_queue',enqueue=>true, dequeue=>true);dbms_aqadm.start_queue('sms_mt_queue',enqueue=>true, dequeue=> true);
C 停止队列
参数的意思参考启动一个队列
Sql代码
dbms_aqadm.stop_queue(sms_mt_queue ',enqueue=>false, dequeue=>true);dbms_aqadm.stop_queue(sms_mt_queue ',enqueue=>false, dequeue=>true);
5 队列操作
说明:
1 入队
Sql代码
P100_MT_ENQUEUE
(
p_equeue_nameInvarchar2,--队列名单大写字母,主队列:SMS_MT_QUEUE 备份队列:SMS_MT_QUEUE_BACKUP
p_bodyInt_outbox_push%Rowtype,--入参,记录类型,数据源头直接调用
p_levelInNumber:=3,--优先级别1-5,数值越小越快
p_delayInNumber:=0,--入队延迟时间,单位:秒
p_res_strOUTVARCHAR2,--0 成功 其它失败
p_msg_idOUTVarchar2--返回的msgid,主键
)P100_MT_ENQUEUE
(
p_equeue_name In varchar2, --队列名单大写字母,主队列:SMS_MT_QUEUE 备份队列:SMS_MT_QUEUE_BACKUP
p_body In t_outbox_push%Rowtype,--入参,记录类型,数据源头直接调用
p_level In Number:=3, --优先级别1-5,数值越小越快
p_delay In Number:=0, --入队延迟时间,单位:秒
p_res_str OUT VARCHAR2, --0 成功 其它失败
p_msg_id OUT Varchar2 --返回的msgid,主键
)2 出队列
Sql代码
p102_mt_dequeue
(
p_equeue_nameInvarchar2,--队列名单大写字母,主队列:SMS_MT_QUEUE 备份队列:SMS_MT_QUEUE_BACKUP
p_client_idOutNumber,--短信内部网关
p_res_strOutvarchar2,--返回值 0 成功 -2 队列为空其它失败
p_labeloutvarchar2,--标签
p_bodyoutvarchar2)--数据包体p102_mt_dequeue
(
p_equeue_name In varchar2, --队列名单大写字母,主队列:SMS_MT_QUEUE 备份队列:SMS_MT_QUEUE_BACKUP
p_client_id Out Number, --短信内部网关
p_res_str Out varchar2, --返回值 0 成功 -2 队列为空其它失败
p_label out varchar2, --标签
p_body out varchar2) --数据包体
3 数据格式转换
Sql代码
p103_change_label_body_str
(
p_dequeue_bodyInMt_Struc,
p_res_strOutVarchar2,
p_labelOutvarchar2,
p_bodyOutvarchar2
)/*
功能:把出队列的字符串翻译成有规则的label,和body
日期:2006-09-20
*/p103_change_label_body_str
(
p_dequeue_body In Mt_Struc,
p_res_str Out Varchar2,
p_label Out varchar2,
p_body Out varchar2
)/*
功能:把出队列的字符串翻译成有规则的label,和body
日期:2006-09-20
*/4 测试入队
Sql代码
procedureP101_MT_ENQUEUE_TEST
(
p_equeue_nameInvarchar2,--队列名单大写字母,主队列:SMS_MT_QUEUE 备份队列:SMS_MT_QUEUE_BACKUP
p_res_stroutVarchar2,
p_msg_idOUTVarchar2
)procedure P101_MT_ENQUEUE_TEST
(
p_equeue_name In varchar2,--队列名单大写字母,主队列:SMS_MT_QUEUE 备份队列:SMS_MT_QUEUE_BACKUP
p_res_str out Varchar2,
p_msg_id OUT Varchar2
)
5.1入队
Sql代码
createorreplaceprocedureP100_MT_ENQUEUE
(
p_equeue_nameInvarchar2,--队列名单大写字母,主队列:SMS_MT_QUEUE 备份队列:SMS_MT_QUEUE_BACKUP
p_bodyInt_outbox_push%Rowtype,--入参,记录类型,数据源头直接调用
p_levelInNumber:=3,--优先级别1-5,数值越小越快
p_delayInNumber:=0,--入队延迟时间,单位:秒
p_res_strOUTVARCHAR2,--0 成功 其它失败
p_msg_idOUTVarchar2--返回的msgid,主键
)/*
功能:数据源头,push,的入队操作
*/
Is
v_enqueue_options dbms_aq.enqueue_options_t;
v_message_properties dbms_aq.message_properties_t;
v_message_handle raw(16);
v_body mt_struc;---写日志区域
vPid NUMBER:=100;
vProName VARCHAR2(50):='P100_MT_ENQUEUE';
vProTip VARCHAR2(255);
vErrorCode VARCHAR2(20);
vErrorMsg VARCHAR2(2000);
Begin
--1初始化
p_res_str:='-1';
--2 P_BODY 到 v_body 的转化 把一个字符串转化为一个结构体
v_body:=mt_struc(
p_body.OP_ID ,
p_body.DEST_MOBILENO ,
p_body.FEE_MOBILENO ,
p_body.LONG_NO ,
p_body.MT_CONTENT ,
p_body.SERVICE_ID ,
p_body.MT_FLAG ,
p_body.MSG_FMT ,
p_body.FEE_TYPE ,
p_body.FEE_VALUE ,
p_body.BEG_REPORT ,
p_body.CLIENT_ID ,
p_body.CLIENT_NAME ,
p_body.MT_TIME ,
p_body.MT_ID ,
p_body.PLAN_ID ,
p_body.PUSH_TYPE ,
p_body.SEND_DATE );
--4设置属性和参数---
--指定异常队列
v_message_properties.exception_queue:='SMS_MT_QUEUE_EXCEPTION';
--设置优先级别
v_message_properties.priority :=p_level;
--设置延时时间--秒
v_message_properties.delay :=p_delay;
--5 开始入队
dbms_aqadm.start_queue(p_equeue_name,enqueue=>true, dequeue=>true);
dbms_aq.enqueue(queue_name=>p_equeue_name,
enqueue_options=>v_enqueue_options,
message_properties=>v_message_properties,
payload=>v_body,
msgid=>v_message_handle);
P_MSG_ID:=v_message_handle ;
--6 commit
Commit;
p_res_str:='0';
Exception
WhenOthersThen
p_res_str:='-100';
vProTip:='入队过程异常!';
vErrorCode:=Sqlcode;
vErrorMsg:=SQLERRM;
p_pub_write_error_log(vPid,vProName,'','',
vProTip,vErrorCode,vErrorMsg,1);
Rollback;
endP100_MT_ENQUEUE;
createorreplaceprocedureP101_MT_ENQUEUE_TEST
(
p_equeue_nameInvarchar2,--队列名单大写字母,主队列:SMS_MT_QUEUE 备份队列:SMS_MT_QUEUE_BACKUP
p_res_stroutVarchar2,
p_msg_idOUTVarchar2
) /*
功能:测试入队
*/
Is
Cursorcur_pushIs
Select*Fromt_outbox_push;
v_row_push t_outbox_push%Rowtype;
v_exe_res varchar2(200);
v_message_handle raw(16);
begin
p_res_str:='-1';
Opencur_push;
Loop
Fetchcur_pushIntov_row_push;
ExitWhencur_push%Notfound;
P100_MT_ENQUEUE(p_equeue_name,v_row_push,3,0,v_exe_res,v_message_handle);
EndLoop;
Closecur_push;
p_res_str:=v_exe_res;
p_msg_id:=v_message_handle;
Exception
WhenOthersThen
p_res_str:=Sqlerrm;
Rollback;
endP101_MT_ENQUEUE_TEST;