使用Python与Cx_Oracle调用带XMLTYPE参数的Oracle存储过程报错咨询
问题原因
你的报错核心是Oracle不会将字符串/CLOB类型隐式转换为XMLTYPE,哪怕XML内容本身符合格式要求,也必须显式执行类型转换。Cx_Oracle文档中说的「XML可按字符串处理」,指的是数据内容可以用字符串承载,不是说可以直接绑定到XMLTYPE类型的参数上。
解决方案
针对修改后的存储过程(第一个参数XMLTYPE入参,第二个VARCHAR出参)
直接在匿名PL/SQL块中对传入的XML字符串执行XMLTYPE()显式转换即可,无需额外创建CLOB对象:
connection = cx_Oracle.connect( config["db"]["usuario"], config["db"]["password"], f"{config['db']['host']}/{config['db']['servicio']}", encoding=config["db"]["nls_charset"], nencoding=config["db"]["nls_ncharset"] ) cursor = connection.cursor() # 直接用字符串承载XML内容即可 xml_in_str = """ <myxml> <sometag>This is some XML</sometag> </myxml> """ # 定义出参变量 po_msgerror = cursor.var(cx_Oracle.STRING) # 执行匿名块,显式转XMLTYPE cursor.execute(""" BEGIN MYPACKAGE_PKG.MYPROCEDURE(XMLTYPE(:1), :2); END; """, [xml_in_str, po_msgerror]) # 获取出参结果 print(po_msgerror.getvalue()) cursor.close() connection.close()
针对原始双XMLTYPE参数的存储过程
如果需要保留出参为XMLTYPE的版本,可以在PL/SQL块内先将XMLTYPE出参转成字符串,再绑定到Python变量:
xml_in_str = """ <myxml> <sometag>This is some XML</sometag> </myxml> """ rxml_out = cursor.var(cx_Oracle.STRING) cursor.execute(""" DECLARE out_xml XMLTYPE; BEGIN MYPACKAGE.MYPROCEDURE(XMLTYPE(:1), out_xml); :2 := out_xml.getStringVal(); END; """, [xml_in_str, rxml_out]) # 获取返回的XML字符串 print(rxml_out.getvalue())
排查 checklist
如果按上述方法仍然报错,请依次确认:
- 存储过程的包名、过程名拼写完全正确,Oracle对象名默认大写,若创建时使用了小写加双引号,需要严格匹配大小写
- 存储过程的参数顺序、参数模式(IN/OUT)和你的调用逻辑完全一致
- 当前数据库用户拥有该存储过程的执行权限
内容的提问来源于stack exchange,提问作者Jaime de los Hoyos M.
相关产品推荐
相关产品推荐

