Sql 使用slice-IN子句的Golang数据库查询

Sql 使用slice-IN子句的Golang数据库查询,sql,go,slice,Sql,Go,Slice,有人能给我解释一下为什么这不起作用吗 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 DIST

有人能给我解释一下为什么这不起作用吗

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)
我试图用一部分int来实现一个简单的IN子句,但所建议的每个解决方案似乎都不是很习惯用法

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

inq := strings.Join(artIds, ",")
我有点惊讶go似乎没有一个优雅的方式来处理这个查询

因为database/sql不检查您的查询,而是通过 参数直接传递给驱动程序,使处理查询 在困难条款中:

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

有一种方法可以处理这些类型的查询,使用它可以更好地控制数据库查询

此模式可以通过首先使用sqlx处理查询来实现。在:

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

有关详细信息,请通过Godoc For

如果您一直小心地从真实整数构建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)
如果您经常这样做,最好有一个where函数来为您实现这一点,或者使用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)

为什么呢?因为
inq
是一个字符串,所以如果你对它进行参数化,你最终会得到
IN('6,7')
,这是有效的,但却是一个非常不同的东西。作为一般规则,中的
不能参数化。你看到了吗:谢谢,我怀疑是这样的。是的,我看到界面重复了一些东西,但对我来说,它闻起来有点怪。我是个新手,所以在动态类型语言中,这是我会有点警惕的。然而,在我的代码中,inq是从int类型的片段生成的,因此它们肯定是int。这是一个很好的做法吗?如果你确定它们是INT,我看没有问题。您编写的任何函数都应该接受整数,而不是字符串。好的,谢谢,这似乎是最简单的解决方案。这实际上是一个技术测试,所以我可能只是警告它的地狱,并表明它已被考虑。谢谢你的信息,非常有价值。那个包裹看起来不错。
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)
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)