jidushanzhu 2026-02-13 17:32 采纳率: 0%
浏览 5

python获取不了输出为ODCIVARCHAR2LIST的存储过程数据

python调用存储过程,获取输出为ODCIVARCHAR2LIST获取不了,返回的数据看不到并显示受保护的特性。sql(创建存储过程)与python代码(调用存储过程)依次为

CREATE OR REPLACE PROCEDURE simple_procedureee(
    p_result OUT SYS.ODCIVARCHAR2LIST
) AS
BEGIN
    p_result := SYS.ODCIVARCHAR2LIST('aaaaaa', 'bbbbb', 'ccccccc');
END;

import cx_Oracle

dsn = cx_Oracle.makedsn("localhost", "1521", 'free')
conn = cx_Oracle.connect('c##scott', 'oracleadmin', dsn=dsn)
cursor = conn.cursor()
out_string = conn.gettype("SYS.ODCIVARCHAR2LIST")
out_string = out_string.newobject()
aa = cursor.callproc('simple_procedureee', (out_string,))
cursor.close()
conn.close()

img

  • 写回答

1条回答 默认 最新

  • 檀越@新空间 2026-02-13 17:33
    关注

    下午好🌅🌅🌅
    本答案参考通义千问

    你遇到的问题是使用 cx_Oracle 调用 Oracle 存储过程时,无法正确获取 SYS.ODCIVARCHAR2LIST 类型的输出参数。这个类型是一个 Oracle 的集合类型(Collection),在 Python 中需要特别处理才能正确获取其内容。


    ✅ 问题分析

    • SYS.ODCIVARCHAR2LIST 是一个 Oracle 集合类型,用于返回多个字符串。
    • 在 Python 中,直接使用 conn.gettype("SYS.ODCIVARCHAR2LIST") 可能会失败或返回受保护的属性,导致无法访问数据。
    • 正确的方法是通过 cursor.callproc() 获取该集合对象,并使用 .getelements() 方法提取元素。

    🛠️ 解决方案

    1. 使用 cursor.callproc() 调用存储过程并获取集合对象

    import cx_Oracle
    
    # 创建 DSN 和连接
    dsn = cx_Oracle.makedsn("localhost", "1521", 'free')
    conn = cx_Oracle.connect('c##scott', 'oracleadmin', dsn=dsn)
    cursor = conn.cursor()
    
    # 定义输出变量为 ODCIVARCHAR2LIST 类型
    out_string = conn.gettype("SYS.ODCIVARCHAR2LIST")
    out_string_obj = out_string.newobject()
    
    # 调用存储过程
    cursor.callproc('simple_procedureee', (out_string_obj,))
    
    # 提取集合中的元素
    result_list = out_string_obj.getelements()
    
    # 打印结果
    print("从存储过程中获取的数据:")
    for item in result_list:
        print(item)
    
    # 关闭连接
    cursor.close()
    conn.close()
    

    2. 注意事项(关键点)

    • 确保 Oracle 客户端版本兼容性cx_Oracle 与 Oracle 客户端版本要匹配,否则可能出现类型解析错误。
    • 使用 getelements() 方法:这是获取集合中元素的标准方式,直接访问 out_string_obj 可能会因为权限或类型限制而失败。
    • 检查用户权限:确保你使用的数据库用户有权限访问 SYS.ODCIVARCHAR2LIST 类型。
    • 避免直接访问受保护属性:某些 Oracle 内置类型可能被封装,不能直接访问其内部结构。

    🔍 代码修改说明

    原始代码中:

    out_string = conn.gettype("SYS.ODCIVARCHAR2LIST")
    out_string = out_string.newobject()
    aa = cursor.callproc('simple_procedureee', (out_string,))
    

    存在问题

    • out_string 是类型对象,但你重新赋值了它,导致后续操作出错。
    • 没有提取集合中的元素。

    修改后的代码

    out_string = conn.gettype("SYS.ODCIVARCHAR2LIST")
    out_string_obj = out_string.newobject()  # 创建集合对象
    cursor.callproc('simple_procedureee', (out_string_obj,))
    result_list = out_string_obj.getelements()  # 提取元素
    

    ✅ 总结

    | 步骤 | 描述 | |------|------| | 1 | 使用 cx_Oracle 连接 Oracle 数据库 | | 2 | 获取 SYS.ODCIVARCHAR2LIST 类型并创建实例 | | 3 | 调用存储过程并将结果存入集合对象 | | 4 | 使用 getelements() 提取集合中的每个元素 | | 5 | 处理和打印结果 |


    如果你仍然遇到问题,请提供完整的错误信息,我可以进一步帮助你排查原因。

    评论

报告相同问题?

问题事件

  • 创建了问题 2月13日