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

如何使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 09:07:48