Golang中解决Sqlx查询错误的方法
Golang中解决Sqlx查询错误的方法
type req_demo struct {
Param1 int `json:"param1" binding:"required"`
Param2 int `json:"param2" binding:"required"`
}
var (
err error
data []resp.data
)
var _req_demo req_demo // dot notation
_req_demo.Param1 = 10
_req_demo.Param2 = 20
Query := `select * from demo fr where fr.param1 = :param1 and fr.param2 = :param1`
err = global.Db.Select(&data, Query, jsonin)
if err != nil {
return nil, err
}
我遇到了 “sql: converting argument $1 type: unsupported type” 错误。
我试图将结构体对象传递给 select 语句。
这个方法中有什么错误?
更多关于Golang中解决Sqlx查询错误的方法的实战教程也可以访问 https://www.itying.com/category-94-b0.html
感谢您的快速回复。
我想将结构体对象作为参数传递给查询。
如果您使用 sqlx 库。
我在更新操作中使用了它。但在选择查询中它不工作。
更多关于Golang中解决Sqlx查询错误的方法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
packs:
我想将参数作为结构体对象传递给查询。
为什么?是Postgresql设定了规则,而 $1、$2 等是传递参数的通用方式。不仅在Go中如此。但是你可以将结果扫描到一个结构体中。不过,由于我出于DRY(不要重复自己)的原因避免使用结构体,所以我无法指导你…
packs: 这个方法有什么错误
我无法完整阅读你的代码。尝试在 Go Playground - The Go Programming Language 中格式化你的代码,并查找“格式化错误”。
但是,你必须在查询中放置一个“占位符”,然后在发送查询时添加参数作为后缀。
var param1, param2 string
query := `SELECT * FROM demo fr WHERE fr.param1=$1 AND fr.param2=$2
err := db.QueryRow(query, ¶m1, ¶m2).Scan(&data)
if err != nil {
return nil, err
}
你的代码示例不完整,所以很难判断。你尝试过给结构体添加 db 标签吗?根据文档:
// 命名查询也可以使用结构体。它们的绑定名称遵循与名称到数据库映射相同的规则,因此结构体字段会被转换为小写,并且会考虑
db标签。
另外,属性 jsonin 在你的代码中任何地方都没有声明。它是从哪里来的?最后,我不熟悉 sqlx,但根据我刚才引用的文档中的那条注释,你确定不应该使用 global.Db.NamedQuery 吗?
这是一个常见的 sqlx 使用错误。问题在于你试图直接将结构体对象传递给查询,但 sqlx 的 Select 方法期望的是查询参数列表,而不是单个结构体。
以下是几种正确的解决方法:
方法1:使用命名参数和结构体映射
type ReqDemo struct {
Param1 int `db:"param1"`
Param2 int `db:"param2"`
}
func queryDemo() ([]RespData, error) {
req := ReqDemo{
Param1: 10,
Param2: 20,
}
query := `SELECT * FROM demo fr WHERE fr.param1 = :param1 AND fr.param2 = :param2`
// 使用 NamedQuery 或 NamedExec 处理命名参数
stmt, err := global.Db.PrepareNamed(query)
if err != nil {
return nil, err
}
defer stmt.Close()
var data []RespData
err = stmt.Select(&data, req)
if err != nil {
return nil, err
}
return data, nil
}
方法2:使用位置参数
func queryDemo() ([]RespData, error) {
req := ReqDemo{
Param1: 10,
Param2: 20,
}
query := `SELECT * FROM demo fr WHERE fr.param1 = $1 AND fr.param2 = $2`
var data []RespData
err := global.Db.Select(&data, query, req.Param1, req.Param2)
if err != nil {
return nil, err
}
return data, nil
}
方法3:使用 map 作为参数
func queryDemo() ([]RespData, error) {
params := map[string]interface{}{
"param1": 10,
"param2": 20,
}
query := `SELECT * FROM demo fr WHERE fr.param1 = :param1 AND fr.param2 = :param2`
var data []RespData
stmt, err := global.Db.PrepareNamed(query)
if err != nil {
return nil, err
}
defer stmt.Close()
err = stmt.Select(&data, params)
if err != nil {
return nil, err
}
return data, nil
}
方法4:使用 sqlx.In 处理 IN 查询(如果需要)
func queryWithIn() ([]RespData, error) {
ids := []int{10, 20, 30}
query, args, err := sqlx.In(`SELECT * FROM demo WHERE id IN (?)`, ids)
if err != nil {
return nil, err
}
query = global.Db.Rebind(query)
var data []RespData
err = global.Db.Select(&data, query, args...)
if err != nil {
return nil, err
}
return data, nil
}
关键问题分析:
- 查询中的参数名错误:你的查询中两个条件都使用了
:param1,应该是:param1和:param2 - 参数传递方式错误:
Select方法不能直接接受结构体作为参数 - 缺少 PrepareNamed:使用命名参数时需要先准备语句
建议使用方法1或方法2,它们是最常用且最清晰的解决方案。

