You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无法从Wrapper过程异步调用Main过程,主过程未执行请求协助

问题描述

我希望从WRAPPER_MAIN_PROC过程异步调用MAIN_PROC过程。目前Wrapper过程的DBMS_OUTPUT.PUT_LINE可以正常输出,但Main过程的输出无显示,疑似Main过程未被成功调用。请协助解决该问题。

相关代码

表脚本

CREATE TABLE ASYNC_SAMPLE_TAB
( attribute1 varchar2(50),
  attribute2 varchar2(50)
);

包规范

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;

包体

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');
问题分析与解决方法

核心问题拆解

  1. DBMS_OUTPUT的局限性:DBMS_OUTPUT的输出仅在当前会话可见,而DBMS_SCHEDULER创建的Job是在独立会话中执行的,所以主过程的输出不会显示在调用Wrapper的会话里,这不是主过程没执行,是输出无法跨会话传递。
  2. Job调用语法错误:Job的PL/SQL块里直接写MAIN_PROC,但该过程属于XX_ASYNC_DEMO_PKG,未指定包名会导致Job执行时抛出“标识符无效”错误,实际主过程根本没跑起来。
  3. 事务未提交:主过程中的INSERT操作没有显式提交,Job执行结束后事务会自动回滚,导致数据没写入表,进一步加深“主过程未执行”的误解。

修复步骤

1. 修正Job中主过程的调用路径

在Job的PL/SQL块里必须指定完整的包名:

job_action => 'BEGIN 
                  XX_ASYNC_DEMO_PKG.MAIN_PROC(''' || attribute1 || ''', ''' || attribute2 || ''');
               END;'

2. 给主过程添加事务提交

确保INSERT的数据能持久化:

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;
        COMMIT; -- 添加提交语句
        DBMS_OUTPUT.PUT_LINE('-- END OF MAIN PROC---' || SYSTIMESTAMP);
    END;

3. 验证Job执行状态

查询USER_SCHEDULER_JOB_RUN_DETAILS确认Job是否成功执行:

SELECT job_name, status, error#, run_date 
FROM USER_SCHEDULER_JOB_RUN_DETAILS 
WHERE job_name LIKE 'ASYNC_MAIN_PROC%';

4. 替换DBMS_OUTPUT为日志表(可选)

如果需要查看主过程的执行日志,建议用日志表替代DBMS_OUTPUT,因为跨会话无法获取其输出:
首先创建日志表:

CREATE TABLE ASYNC_PROC_LOG (
    log_time TIMESTAMP,
    proc_name VARCHAR2(50),
    log_msg VARCHAR2(200)
);

然后修改主过程写入日志:

PROCEDURE MAIN_PROC( 
        attribute1          IN      VARCHAR2,
        attribute2          IN      VARCHAR2
    )
    AS
        sql_stmt    VARCHAR2(200);
    BEGIN
        INSERT INTO ASYNC_PROC_LOG VALUES(SYSTIMESTAMP, 'MAIN_PROC', '-- START OF MAIN PROC---');
        DBMS_SESSION.sleep(10);
        sql_stmt := 'INSERT INTO ASYNC_SAMPLE_TAB VALUES (:1, :2)';
        EXECUTE IMMEDIATE sql_stmt USING attribute1, attribute2;
        COMMIT;
        INSERT INTO ASYNC_PROC_LOG VALUES(SYSTIMESTAMP, 'MAIN_PROC', '-- END OF MAIN PROC---');
        COMMIT;
    END;

验证方法

执行测试命令后,等待10秒以上,查询ASYNC_SAMPLE_TAB是否有新增数据,或查询ASYNC_PROC_LOG查看日志,同时通过USER_SCHEDULER_JOB_RUN_DETAILS确认Job执行状态。


内容的提问来源于stack exchange,提问作者mu shaikh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 17:55:18