如何使用GORM获取存储过程的return_value返回值
问题原因及解决方案
存储过程的返回值完全可以在SQL外部获取,你遇到的问题是代码写法错误导致的,主要有以下几处问题:
- 结构体字段未导出:Go语言中只有首字母大写的结构体字段才可被反射访问,你定义的
returnVal首字母为小写,GORM的Scan方法无法为该字段赋值。 - SQL别名语法错误:你的查询语句中
select 'res' = @return_val给列别名加了单引号,SQL会将'res'识别为字符串常量而非结果集列名,这也是你日志中出现select 'res' = NULL的直接原因。 - 存储过程调用语法缺分隔:执行存储过程的语句中,存储过程名和后续参数之间缺少分隔符,会导致语法执行错误,最终
@return_val未被正确赋值。
修正后的代码
1. 修正结构体定义
type Res struct { ReturnVal int `gorm:"column:res"` }
2. 修正SQL执行语句
var res Res err := db.Raw("DECLARE @return_val INT; EXEC @return_val = ?, @p1 = ?; SELECT res = @return_val", sprocName, param1).Scan(&res).Error if err != nil { // 处理执行错误 } // res.ReturnVal 即为存储过程返回值
特殊情况处理
如果你的存储过程内部本身有SELECT语句输出业务结果集,返回值的结果集会排在业务结果集之后,需要遍历多个结果集获取:
rows, err := db.Raw("DECLARE @return_val INT; EXEC @return_val = ?, @p1 = ?; SELECT res = @return_val", sprocName, param1).Rows() if err != nil { // 处理错误 } defer rows.Close() // 先遍历存储过程返回的业务结果集 for rows.Next() { // 扫描业务数据逻辑 } // 切换到返回值的结果集 if rows.NextResultSet() { var returnVal int if err := rows.Scan(&returnVal); err == nil { // returnVal 即为存储过程返回值 } }
内容的提问来源于stack exchange,提问作者hhqhhq
相关产品推荐
相关产品推荐

