当我试图动态清除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;
/
匿名阻止完成
答案 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:
此过程在自治事务中提交批量消息。