繁体   English   中英

Golang db 查询使用 slice IN 子句

[英]Golang db query using slice IN clause

有人可以向我解释为什么这不起作用吗?

inq := "6,7" //strings.Join(artIds, ",")
rows, err = db.Query("SELECT DISTINCT title FROM tags_for_articles LEFT JOIN tags ON tags.id = tags_for_articles.tag_id WHERE article_id IN (?)", inq)

这确实

rows, err = db.Query("SELECT DISTINCT title FROM tags_for_articles LEFT JOIN tags ON tags.id = tags_for_articles.tag_id WHERE article_id IN (6,7)", inq)

我正在尝试用一个整数切片做一个简单的 IN 子句,并且建议的每个解决方案似乎都不太惯用

试图这样做,但问题似乎是字符串替换。

inq := strings.Join(artIds, ",")

我有点惊讶 go 似乎没有一种优雅的方式来处理这个查询。

由于 database/sql 不会检查您的查询,而是将您的参数直接传递给驱动程序,因此很难处理带有 IN 子句的查询:

SELECT * FROM users WHERE level IN (?);

当它准备好作为后端的语句时, bindvar ? 将只对应一个参数,但通常需要的是根据某个切片的长度,它是可变数量的参数

var levels = []int{4, 6, 7}
rows, err := db.Query("SELECT * FROM users WHERE level IN (?);", levels)

有一种方法可以使用sqlx处理这些类型的查询, sqlx提供对数据库查询的更多控制。

这种模式可以通过首先使用 sqlx.In 处理查询来实现:

var levels = []int{4, 6, 7}
query, args, err := sqlx.In("SELECT * FROM users WHERE level IN (?);", levels)

有关更多信息,请访问 Godoc for InQuery

如果您小心地从真实整数构建您的 inq 字符串(以避免注入),您可以自己构建字符串并避免使用 ?:

inq := "6,7" 
sql := fmt.Sprintf("SELECT DISTINCT title FROM tags_for_articles LEFT JOIN tags ON tags.id = tags_for_articles.tag_id WHERE article_id IN (%s)",inq)
rows, err := db.Query(sql)

如果您经常这样做,最好有一个 WhereIn 函数为您执行此操作,或者使用 orm。 但是请注意您接受哪些参数,就好像您接受任意字符串一样可以注入任何内容。

您需要“?”的数量在“IN”子句中匹配参数的数量,所以你需要做这样的事情:

inq := "6,7" //strings.Join(artIds, ",")
qms := strings.Repeat("?,", len(inq))
qms = params[:len(params)-1] // remove the trailing ","

rows, err = db.Query("SELECT DISTINCT title FROM tags_for_articles LEFT JOIN tags ON tags.id = tags_for_articles.tag_id WHERE article_id IN (" + qms + ")", inq)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM