如何使用pandas的read_sql调用带参数的Oracle存储过程?
Oracle存储过程调用错误排查与修正
问题详情
创建的Oracle存储过程:
create or replace PROCEDURE MyTestProcedure(p_date IN DATE) AS OUTPUT SYS_REFCURSOR; BEGIN END
使用pandas read_sql调用的代码:
pd.read_sql("""EXECUTE MyTestProcedure @p_date=(TO_DATE('2022-02-01','YYYY-MM-DD'))""")
执行后报错:
DatabaseError: Execution failed on sql 'EXECUTE MyTestProcedure @p_date=(TO_DATE('2022-02-01','YYYY-MM-DD'))': ORA-00900: invalid SQL statement
错误原因及解决步骤
1. 调用语法不符合Oracle规则
Oracle里调用存储过程的语法和你写的不一致:
- 不能用
@p_date=这种格式传参,Oracle参数传递不需要@前缀,直接传递值即可 EXECUTE命令在SQL环境中使用时,基础格式是EXECUTE 存储过程名(参数值),但如果涉及输出游标,必须用PL/SQL块包裹才能返回结果
2. 存储过程定义有缺陷
你定义的OUTPUT SYS_REFCURSOR没有声明为输出参数,pandas无法获取返回结果。必须明确标注游标参数的模式为OUT。
修正后的存储过程
create or replace PROCEDURE MyTestProcedure(p_date IN DATE, p_result OUT SYS_REFCURSOR) AS BEGIN -- 替换为你的实际业务查询,示例为查询指定日期的数据 OPEN p_result FOR SELECT * FROM your_table WHERE date_column = p_date; END;
修正后的pandas调用代码
通过PL/SQL块处理游标输出,结合数据库驱动获取结果:
import pandas as pd import cx_Oracle # 建立数据库连接(替换为你的实际连接信息) conn = cx_Oracle.connect("用户名/密码@主机:端口/服务名") # 调用存储过程的PL/SQL语句 sql = """ DECLARE cur SYS_REFCURSOR; BEGIN MyTestProcedure(TO_DATE('2022-02-01','YYYY-MM-DD'), cur); :result := cur; END; """ # 读取结果,传入游标类型的绑定变量 df = pd.read_sql(sql, conn, params={"result": cx_Oracle.CURSOR}) # 关闭连接 conn.close()
也可以用更简洁的写法:
df = pd.read_sql("BEGIN MyTestProcedure(TO_DATE('2022-02-01','YYYY-MM-DD'), :cur); END;", conn, params={"cur": cx_Oracle.CURSOR})
3. 额外注意事项
- 确保已正确安装并配置Oracle数据库驱动(如cx_Oracle)
- 存储过程中必须通过
OPEN ... FOR语句给游标赋值查询结果,否则pandas无法读取到数据
内容的提问来源于stack exchange,提问作者TourEiffel
相关产品推荐
相关产品推荐

