Python使用cx_Oracle调用带IN/OUT参数的Oracle函数报ORA-01036如何解决
问题原因&修复方案
错误点梳理
- 绑定变量未加前缀冒号:所有在PL/SQL块中引用的Python传入绑定变量,必须以
:作为前缀,你在赋值本地变量时直接写了inout_theKey等变量名,Oracle识别为未声明的本地PL/SQL变量,触发绑定错误。 - 语法错误:第一个匿名块中调用函数时,
theName和theEmail参数之间缺少逗号,且函数调用行末尾缺少分号。 - 拼写错误:带DECLARE的版本中
inout_ttheKey多写了一个t,变量名不匹配。 - 日期类型传值错误:直接传入空字符串给DATE类型参数会触发类型转换错误,需要传入
None对应Oracle的空值。 - 逻辑错误:DECLARE块中直接将输出绑定变量作为本地变量初始值,此时输出变量还未赋值,逻辑不成立。
修正后的代码
import cx_Oracle cursor = connection.cursor() # 修正后的PL/SQL块,完全对齐你在Oracle Developer中运行的逻辑 plsql = ''' DECLARE theId VARCHAR(20); theKey VARCHAR(20) := :inout_theKey; theName VARCHAR(20) := :in_theName; theEmail VARCHAR(20) := :in_theEmail; theDob DATE := :in_theDob; theVal NUMBER; BEGIN theId := Package.FunctionName( theKey, theName, theEmail, theDob, theVal ); :out_theId := theId; :out_theKey := theKey; :out_theVal := theVal; EXCEPTION WHEN OTHERS THEN RAISE; END; ''' # 声明绑定变量,指定长度匹配数据库字段定义避免截断 out_theId = cursor.var(str, 20) out_theVal = cursor.var(int) inout_theKey = cursor.var(str, 20) inout_theKey.setvalue(0, '') # 执行绑定,日期参数传None而非空字符串 cursor.execute( plsql, inout_theKey=inout_theKey, in_theName='', in_theEmail='', in_theDob=None, out_theId=out_theId, out_theVal=out_theVal ) # 读取返回值 _logger.debug(out_theId.getvalue()) _logger.debug(out_theKey.getvalue()) _logger.debug(out_theVal.getvalue())
更简便的调用方式:使用cx_Oracle原生callfunc
cx_Oracle提供了直接调用存储函数的方法,无需手动写PL/SQL块:
cursor = connection.cursor() # 声明IN/OUT、OUT参数 theKey = cursor.var(str, 20) theKey.setvalue(0, '') theVal = cursor.var(int) # 按函数定义顺序传入参数,IN参数直接传值,IN/OUT/OUT参数传变量对象 theId = cursor.callfunc( 'Package.FunctionName', str, # 函数返回值类型 [theKey, '', '', None, theVal] ) # 读取结果 _logger.debug(theId) _logger.debug(theKey.getvalue()) _logger.debug(theVal.getvalue())
内容的提问来源于stack exchange,提问作者Christoph Farnleitner
相关产品推荐
相关产品推荐

