Go使用go-ora/v2调用Oracle包获取REFCURSOR输出报错
问题背景
在Oracle数据库中创建测试包如下:
CREATE OR REPLACE PACKAGE PKG_TEST IS TYPE REFCURSOR IS REF CURSOR; PROCEDURE PROC_GET_DUAL(P_CUR OUT REFCURSOR); end PKG_TEST; / CREATE OR REPLACE PACKAGE BODY PKG_TEST is PROCEDURE PROC_GET_DUAL( P_CUR OUT REFCURSOR) IS BEGIN OPEN P_CUR FOR select * from dual; END PROC_GET_DUAL; end PKG_TEST; /
使用Golang的github.com/sijms/go-ora/v2驱动连接Oracle,ping检测连通正常,最初编写的调用代码如下:
var cursor go_ora.RefCursor fmt.Println(db.Ping()) statement := `begin :x := PKG_TEST.PROC_GET_DUAL(); end;` _, err := db.Exec(statement, sql.Out{Dest: &cursor}) //check errors defer cursor.Close() rows, err := cursor.Query() // check for error var ( var1 string ) for rows.Next_() { err = rows.Scan(&var1) // check for error fmt.Println(var1) }
参考驱动文档编写代码但执行时报错,核心报错信息如下:
PLS-00222: no function with name 'PROC_GET_DUAL' exists in this scope
ORA-06550: line 1, column 13:
PL/SQL: Statement ignored
报错原因
核心问题是混淆了Oracle存储过程和函数的调用语法:
- 定义的
PROC_GET_DUAL是存储过程,没有返回值,结果游标通过参数列表的OUT类型参数传出 - 编写的调用语句
:x := PKG_TEST.PROC_GET_DUAL()是函数调用语法,执行时会去查找名为PROC_GET_DUAL、无入参、带返回值的函数,找不到对应对象就会触发PLS-00222错误。
修复方案
- 修改PL/SQL调用语句,改为存储过程的标准调用格式,将游标占位符作为存储过程的入参传入,不要使用赋值语法:
begin PKG_TEST.PROC_GET_DUAL(:x); end; - 调整Go代码逻辑,补充错误校验和资源释放操作,修正后完整可运行代码:
var cursor go_ora.RefCursor // 校验ping错误,不要仅打印返回值不做处理 err := db.Ping() if err != nil { panic(err) } fmt.Println("数据库连通正常") // 修正为存储过程调用语法 statement := `begin PKG_TEST.PROC_GET_DUAL(:x); end;` _, err = db.Exec(statement, sql.Out{Dest: &cursor}) if err != nil { panic(err) } defer cursor.Close() rows, err := cursor.Query() if err != nil { panic(err) } defer rows.Close() // 主动关闭结果集,避免游标资源泄漏 var var1 string // go-ora v2版本遍历使用Next()即可,旧版本Next_()已废弃 for rows.Next() { err = rows.Scan(&var1) if err != nil { panic(err) } fmt.Println(var1) }
修复后执行即可正常输出dual表的X字段值。
内容的提问来源于stack exchange,提问作者htan
相关产品推荐
相关产品推荐

