有人可以向我解释为什么这行不通吗?
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似乎没有一种优雅的方式来处理此查询感到惊讶。
答案 0 :(得分:1)
因为数据库/ 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
package处理这些类型的查询的方法,它可以更好地控制数据库查询。
可以通过首先使用sqlx.In处理查询来实现此模式。
var levels = []int{4, 6, 7}
query, args, err := sqlx.In("SELECT * FROM users WHERE level IN (?);", levels)
有关更多信息,请通过Godoc获得InQueries
答案 1 :(得分:1)
如果您一直很小心地从实数整数构建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。但是要小心接受哪些参数,就像接受任意字符串一样。
答案 2 :(得分:0)
您需要“?”的数量在“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)