首页 > 解决方案 > 如何通过 cx_Oracle 模块 API 正确调用 fnd_concurrent.wait_for_request 存储函数?

问题描述

我正在尝试通过fnd_concurrent.wait_for_request使用 Python cx_Oracle 模块调用存储过程来等待 Oracle 中提交的请求,但遇到错误:cx_Oracle.DatabaseError: ORA-06502: PL/SQL: numeric or value error

FND_CONCURRENT.WAIT_FOR_REQUEST 具有以下签名:(来自文档https://docs.oracle.com/cd/E18727_01/doc.121/e12897/T302934T458258.htm

function FND_CONCURRENT.WAIT_FOR_REQUEST  

(request_id IN number default NULL,
          interval   IN number default 60,
          max_wait   IN number default 0,
          phase      OUT varchar2,
          status     OUT varchar2,
          dev_phase  OUT varchar2,
          dev_status OUT varchar2,
          message    OUT varchar2) return  boolean;

我用python代码调用它:

...
lc_phase = cursor.var(str)
lc_status = cursor.var(str)
lc_dev_phase = cursor.var(str)
lc_dev_status = cursor.var(str)
lc_message = cursor.var(str)

bool_result = cursor.callfunc('fnd_concurrent.wait_for_request', bool, [123456789,5,15,lc_phase,lc_status,lc_dev_phase,lc_dev_status,lc_message])

print('fnd_concurrent.wait_for_request result: ', bool_result)
...

我确实尝试了不同类型的输出参数,例如cx_Oracle.DB_TYPE_VARCHARandcx_Oracle.STRING但结果相同。

错误描述了与cursor.callfunc()调用完全一致的问题

标签: pythonoracleplsqlcx-oracle

解决方案


我没有看到这个测试用例的错误:

import cx_Oracle
import os
import sys

"""

create or replace function my_wait_for_request
  (request_id IN number default NULL,
          interval   IN number default 60,
          max_wait   IN number default 0,
          phase      OUT varchar2,
          status     OUT varchar2,
          dev_phase  OUT varchar2,
          dev_status OUT varchar2,
          message    OUT varchar2) return boolean
as
begin
  phase := 'my phase';
  status := 'my status';
  dev_phase := 'my dev_phase';
  dev_status := 'my dev_status';
  message := 'my message';
  return(true);
end;
/

show errors

"""

if sys.platform.startswith("darwin"):
    cx_Oracle.init_oracle_client(lib_dir=os.environ.get("HOME")+"/Downloads/instantclient_19_8")

username = os.environ.get("PYTHON_USERNAME")
password = os.environ.get("PYTHON_PASSWORD")
connect_string = os.environ.get("PYTHON_CONNECTSTRING")

connection = cx_Oracle.connect(username, password, connect_string)

cursor = connection.cursor()

lc_phase = cursor.var(str)
lc_status = cursor.var(str)
lc_dev_phase = cursor.var(str)
lc_dev_status = cursor.var(str)
lc_message = cursor.var(str)

bool_result = cursor.callfunc('my_wait_for_request', bool, [123456789,5,15,lc_phase,lc_status,lc_dev_phase,lc_dev_status,lc_message])

print('my_wait_for_request result: ', bool_result)
print(lc_phase.getvalue(),lc_status.getvalue(),lc_dev_phase.getvalue(),lc_dev_status.getvalue(),lc_message.getvalue())

输出是:

my_wait_for_request result:  True
my phase my status my dev_phase my dev_status my message

推荐阅读