如何在AQADMIN中动态清除表

时间:2018-03-05 09:21:05

标签: oracle plsql

当我试图动态清除QUEUE表时,我收到错误.Below是代码

 set serveroutput on;
declare
l_stmt varchar2(2000):='';
po_t dbms_aqadm.aq$_purge_options_t;
BEGIN
for i in (select NAME,queue_table from all_Queues where owner='AQADMIN') loop
--dbms_output.put_line(i.queue_table);
l_stmt:='DBMS_AQADM.PURGE_QUEUE_TABLE ('''||i.queue_table||''',''trunc(enq_time)<sysdate-90'',block => po_t)';
execute immediate l_stmt;
--dbms_output.put_line(l_stmt);
commit;
end loop;
END;
/

错误讯息:

Error report -
ORA-00900: invalid SQL statement
ORA-06512: at line 8
00900. 00000 -  "invalid SQL statement"
*Cause:    
*Action:

要知道我的查询框架是否正确,我注释掉了执行立即部分并取消注释了DBMS_OUTPUT命令,结果发布在sql developer中并且执行完美,(下面是代码输出)。所以查询是是的,不确定我的代码有什么问题,

输出:

anonymous block completed

    DBMS_AQADM.PURGE_QUEUE_TABLE ('HEARTBEAT_MSG_QT','trunc(enq_time)<sysdate-90',block => po_t)

然后我在单独的SQL块中执行了上面的输出,它运行正常.Below

declare
po_t dbms_aqadm.aq$_purge_options_t;
begin
DBMS_AQADM.PURGE_QUEUE_TABLE ('HEARTBEAT_MSG_QT','trunc(enq_time)<sysdate-90',po_t);
end;
/

匿名阻止完成

1 个答案:

答案 0 :(得分:3)

当你致电execute immediate时,它是expecting dynamic SQL,而不是PL / SQL。要运行PL / SQL命令,您需要将其包装在匿名块中,就像您手动运行它时一样:

l_stmt:='DECLARE po_t dbms_aqadm.aq$_purge_options_t; BEGIN DBMS_AQADM.PURGE_QUEUE_TABLE ('''||i.queue_table||''',''trunc(enq_time)<sysdate-90'',block => po_t); END;';

或分成多行以使其更容易阅读:

l_stmt:='DECLARE po_t dbms_aqadm.aq$_purge_options_t;'
  || 'BEGIN '
  || 'DBMS_AQADM.PURGE_QUEUE_TABLE ('''||i.queue_table||''','
  || '''trunc(enq_time)<sysdate-90'',block => po_t);'
  || 'END;';

请注意,您必须在该块中重新声明po_t,因为原始声明超出了动态SQL调用的范围(实际上,原始声明现在是冗余的......)。

您不需要使用动态SQL,您可以将游标值直接传递给过程:

DECLARE
  l_po dbms_aqadm.aq$_purge_options_t;
BEGIN
  for i in (select NAME,queue_table from all_Queues where owner='AQADMIN') 
  loop
    DBMS_AQADM.PURGE_QUEUE_TABLE (queue_table => i.queue_table,
      purge_condition => 'trunc(enq_time)<sysdate-90'
      purge_options=> l_po);
  end loop;
END;
/

我还删除了commit,因为它是多余的; from the docs

  

此过程在自治事务中提交批量消息。