如何使用cx_Oracle解析Oracle存储过程返回的TAB类型输出
解决方案
首先先修正你Oracle存储过程里的语法错误,否则存储过程无法正常编译执行:
-- 修正后的自定义对象类型 CREATE OR REPLACE TYPE xyz.OUTPUT_TYP IS OBJECT( A VARCHAR(20), B VARCHAR(20), dt TIMESTAMP(6) ); -- 修正后的自定义表类型 CREATE OR REPLACE TYPE xyz.OUTPUT_TYPE_TAB IS TABLE OF xyz.OUTPUT_TYP; -- 修正后的存储过程 CREATE OR REPLACE PROCEDURE xyz.XYZ_PROC( IN_DT IN DATE, tab_out OUT xyz.OUTPUT_TYPE_TAB ) AS BEGIN tab_out := xyz.OUTPUT_TYPE_TAB(); SELECT xyz.OUTPUT_TYP(A, B, dt) BULK COLLECT INTO tab_out FROM tab_x WHERE ...; -- 替换为你的实际过滤条件 END XYZ_PROC;
然后是Python中解析输出对象Out_obj的代码:
def get_impl(): # 初始化连接(假设get_conn()返回cx_Oracle连接池的有效连接) connection = get_conn() cur = connection.cursor() # 获取自定义表类型,注意带上所属用户前缀 obj_type = connection.gettype("xyz.OUTPUT_TYPE_TAB") out_obj = obj_type.newobject() # 注意:IN_DT是DATE类型,需传入Python日期对象而非字符串 import datetime input_date = datetime.date.today() # 替换为你的实际输入日期 # 调用存储过程 cur.execute("BEGIN xyz.XYZ_PROC(:1, :2); END;", [input_date, out_obj]) # 解析输出对象 result = [] # 遍历表类型的每一行元素 for item in out_obj: # 每个item是OUTPUT_TYP实例,直接访问对应属性 result.append({ 'A': item.A, 'B': item.B, 'dt': item.dt }) # 此时result就是结构化的查询结果 print(result) # 清理资源 cur.close() connection.close()
关键说明
- 直接打印
out_obj只会输出对象内存引用,看不到实际数据,必须遍历其元素 - 自定义对象的属性名要和Oracle中
OUTPUT_TYP的定义完全一致(大小写敏感取决于Oracle配置,建议严格匹配) - 输入参数
IN_DT为DATE类型,不能传字符串,需传入datetime.date或datetime.datetime对象 - 如果自定义类型不属于当前连接用户,必须指定完整的
用户.类型名格式
内容的提问来源于stack exchange,提问作者LearnDaily
相关产品推荐
相关产品推荐

