[英]unable to call main procedure from wrapper procedure asynchronously
我想从包装程序调用主程序。 包装程序我可以使用 dbms output 打印行 output 但我无法在主过程中打印,看起来主过程不是从包装程序调用的。 请帮我
下面是表格脚本
CREATE TABLE ASYNC_SAMPLE_TAB
( attribute1 varchar2(50),
attribute2 varchar2(50)
);
下面是我的 package 规格
CREATE OR REPLACE PACKAGE XX_ASYNC_DEMO_PKG
IS
PROCEDURE MAIN_PROC(
attribute1 IN VARCHAR2,
attribute2 IN VARCHAR2
);
PROCEDURE WRAPPER_MAIN_PROC(
attribute1 IN VARCHAR2,
attribute2 IN VARCHAR2
);
END XX_ASYNC_DEMO_PKG;
下面是我的 package bofy
CREATE OR REPLACE PACKAGE BODY XX_ASYNC_DEMO_PKG
IS
PROCEDURE WRAPPER_MAIN_PROC(
attribute1 IN VARCHAR2,
attribute2 IN VARCHAR2
)
AS
BEGIN
DBMS_OUTPUT.PUT_LINE('-- START OF WRAPPER PROC---' || SYSTIMESTAMP);
dbms_scheduler.create_job(
job_name => 'ASYNC_MAIN_PROC' || '_' || attribute1,
job_type => 'PLSQL_BLOCK',
job_action => 'BEGIN
MAIN_PROC(''' || attribute1 || ''', ''' || attribute2 || ''');
END;',
start_date => systimestamp ,
auto_drop => true,
enabled => true
);
DBMS_OUTPUT.PUT_LINE('-- END OF WRAPPER PROC---' || SYSTIMESTAMP);
END;
PROCEDURE MAIN_PROC(
attribute1 IN VARCHAR2,
attribute2 IN VARCHAR2
)
AS
sql_stmt VARCHAR2(200);
BEGIN
DBMS_OUTPUT.PUT_LINE('-- START OF MAIN PROC---' || SYSTIMESTAMP);
DBMS_SESSION.sleep(10);
sql_stmt := 'INSERT INTO ASYNC_SAMPLE_TAB VALUES (:1, :2)';
EXECUTE IMMEDIATE sql_stmt USING attribute1, attribute2;
DBMS_OUTPUT.PUT_LINE('-- END OF MAIN PROC---' || SYSTIMESTAMP);
END;
END XX_ASYNC_DEMO_PKG;
下面是我试图用来测试上述解决方案的命令
exec XX_ASYNC_DEMO_PKG.WRAPPER_MAIN_PROC('Test101_1', 'Test101_2');
如文档中所述, DBMS_OUTPUT
的主要目的是调试消息以跟踪执行流程。 那里还说它不会立即向调用者返回任何内容,但文本会被放入缓冲区中,并且可以由调用者或程序本身从那里检索(尽管你不能“进入”任何其他程序流程和从执行代码中获取任何东西,直到被调用单元完成)。
调度程序在完成作业后不会检索缓冲区的内容,因此在后台作业中调用的DBMS_OUTPUT.PUT*
没有任何效果,您也看不到任何结果。
您可以使用一些日志记录表(在自治事务中执行单独的日志记录过程,不影响或受主事务影响)或外部文件和UTL_FILE
将结果发送到此处。 或者使用应该由作业处理的通用表,并在完成后检查结果。
UPD :下面是一个完整的设置,用于演示如何将参数传递给可调用对象并查看其结果。
create table log_table (
ts timestamp,
val number,
job_name varchar2(30)
)
create or replace procedure proc_insert(
p_val in number,
p_job_name in varchar2
) as
begin
insert into log_table(ts, val, job_name)
values (systimestamp, p_val, p_job_name);
commit;
end;
DBMS_SCHEDULER.SET_JOB_[ARGUMENT|ANYDATA]_VALUE
。create or replace procedure proc_insert_async( p_call_id varchar2, p_val number, r_job_name out varchar2 ) as l_job_prefix constant varchar2(20):= 'LOG_TABLE_'; l_job_name varchar2(100):= l_job_prefix || p_call_id; begin dbms_scheduler.create_job( job_name => l_job_name, job_type => 'STORED_PROCEDURE', /*Callable unit - out API procedure*/ job_action => 'TEST_EAS.PROC_INSERT', /*Number of args to be passed to the proc*/ number_of_arguments => 2, /*Run immediately*/ start_date => sysdate, enabled => false, auto_drop => true ); /*Pass parameters to the callable*/ dbms_scheduler.set_job_anydata_value ( job_name => l_job_name, argument_position => 1, argument_value => sys.anydata.convertNumber(p_val) ); dbms_scheduler.set_job_argument_value( job_name => l_job_name, argument_position => 2, argument_value => l_job_name ); /*Start job*/ dbms_scheduler.enable( name => l_job_name ); r_job_name:= l_job_name; end;
declare l_job_name varchar2(100); begin proc_insert_async( p_call_id => 'test1', p_val => 1, r_job_name => l_job_name ); dbms_output.put_line(l_job_name); proc_insert_async( p_call_id => 'test2', p_val => 10, r_job_name => l_job_name ); dbms_output.put_line(l_job_name); dbms_session.sleep(3); end; / LOG_TABLE_test1 LOG_TABLE_test2 PL/SQL procedure successfully completed.
select *
from log_table
TS | 值 | JOB_NAME |
---|---|---|
25.11.22 10:52:37,310403000 | 10 | LOG_TABLE_test2 |
25.11.22 10:52:37,302992000 | 1个 | LOG_TABLE_test1 |
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.