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

5 回复

感谢您的快速回复。

我想将结构体对象作为参数传递给查询。

如果您使用 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, &param1, &param2).Scan(&data)
if err != nil {
   return nil, err
}

你的代码示例不完整,所以很难判断。你尝试过给结构体添加 db 标签吗?根据文档

// 命名查询也可以使用结构体。它们的绑定名称遵循与名称到数据库映射相同的规则,因此结构体字段会被转换为小写,并且会考虑 db 标签。

另外,属性 jsonin 在你的代码中任何地方都没有声明。它是从哪里来的?最后,我不熟悉 sqlx,但根据我刚才引用的文档中的那条注释,你确定不应该使用 global.Db.NamedQuery 吗?

这是一个常见的 sqlx 使用错误。问题在于你试图直接将结构体对象传递给查询,但 sqlxSelect 方法期望的是查询参数列表,而不是单个结构体。

以下是几种正确的解决方法:

方法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
}

关键问题分析:

  1. 查询中的参数名错误:你的查询中两个条件都使用了 :param1,应该是 :param1:param2
  2. 参数传递方式错误Select 方法不能直接接受结构体作为参数
  3. 缺少 PrepareNamed:使用命名参数时需要先准备语句

建议使用方法1或方法2,它们是最常用且最清晰的解决方案。

回到顶部