Django调用Oracle存储过程提示找不到fetchall,如何获取返回的结果集
Django调用Oracle返回REF CURSOR存储过程的结果集获取方案
错误原因
你调用cursor.fetchall()报错的核心原因是:执行callproc的主游标本身没有绑定查询结果集,存储过程返回的结果集实际存放在你声明的cx_Oracle.CURSOR类型的输出变量中,不能用原主游标执行fetch操作。
正确实现代码
import cx_Oracle # 数据库连接配置 dsn_tns = cx_Oracle.makedsn('host', '10710', service_name='sname') conn = cx_Oracle.connect(user=r'user', password='pass', dsn=dsn_tns) cursor = conn.cursor() # 按存储过程参数顺序构造参数,第一个为入参val的实际值 params = ['你的入参值'] # 定义输出游标变量 out_cursor = cursor.var(cx_Oracle.CURSOR) params.append(out_cursor) # 调用存储过程 cursor.callproc('test_proc', params) # 获取返回的结果集游标,直接用该游标执行fetch操作 result_cursor = out_cursor.getvalue() rows = result_cursor.fetchall() # 资源释放 result_cursor.close() cursor.close() conn.close()
Django原生连接优化写法
Django已经封装了数据库连接生命周期管理,更推荐直接使用Django自带的数据库连接获取游标:
from django.db import connection def get_proc_result(): with connection.cursor() as cursor: out_cursor = cursor.var(cx_Oracle.CURSOR) # 按顺序传入入参、出参 cursor.callproc('test_proc', ['入参值', out_cursor]) result_cursor = out_cursor.getvalue() # 获取结果集 rows = result_cursor.fetchall() # 可选:提取字段名转成字典列表 columns = [col[0] for col in result_cursor.description] formatted_result = [dict(zip(columns, row)) for row in rows] result_cursor.close() return formatted_result
注意事项
- 存储过程的传参顺序必须和定义的参数顺序完全匹配,示例中的存储过程第一个为NVARCHAR2类型入参,第二个为SYS_REFCURSOR类型出参,不要传反顺序
- 返回的结果集游标
result_cursor的用法和普通查询游标完全一致,支持fetchone()、fetchmany()、fetchall()等常用方法 - 结果集游标使用后需要手动关闭,避免资源泄漏
内容的提问来源于stack exchange,提问作者Nikesh Kedlaya
相关产品推荐
相关产品推荐

