加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

postgresql – Postgres中的Go和IN子句

发布时间:2020-12-13 16:18:58 所属栏目:百科 来源:网络整理
导读:我试图使用 pq driver对Go中的PostgreSQL数据库执行以下查询: SELECT COUNT(id)FROM tagsWHERE id IN (1,2,3) 其中1,3在切片标签处传递:= [] string {“1”,“2”,“3”}. 我尝试了很多不同的东西,比如: s := "(" + strings.Join(tags,",") + ")"if err :
我试图使用 pq driver对Go中的PostgreSQL数据库执行以下查询:
SELECT COUNT(id)
FROM tags
WHERE id IN (1,2,3)

其中1,3在切片标签处传递:= [] string {“1”,“2”,“3”}.

我尝试了很多不同的东西,比如:

s := "(" + strings.Join(tags,",") + ")"
if err := Db.QueryRow(`
    SELECT COUNT(id)
    FROM tags
    WHERE id IN $1`,s,).Scan(&num); err != nil {
    log.Println(err)
}

这导致pq:语法错误在“$1”或附近.我也试过了

if err := Db.QueryRow(`
    SELECT COUNT(id)
    FROM tags
    WHERE id IN ($1)`,strings.Join(stringTagIds,"),).Scan(&num); err != nil {
    log.Println(err)
}

这也失败了pq:整数的输入语法无效:“1,3”

我也尝试直接传递一片整数/字符串并得到sql:转换Exec参数#0的类型:不支持的type []字符串,一个切片.

那么如何在Go中执行此查询?

预构建SQL查询(防止SQL注入)

如果您为每个值生成带有param占位符的SQL字符串,则可以更轻松地立即生成最终SQL.

请注意,由于值是字符串,因此存在SQL注入攻击的位置,因此我们首先测试所有字符串值是否确实是数字,我们只在这样做:

tags := []string{"1","2","3"}
buf := bytes.NewBufferString("SELECT COUNT(id) FROM tags WHERE id IN(")
for i,v := range tags {
    if i > 0 {
        buf.WriteString(",")
    }
    if _,err := strconv.Atoi(v); err != nil {
        panic("Not number!")
    }
    buf.WriteString(v)
}
buf.WriteString(")")

执行它:

num := 0
if err := Db.QueryRow(buf.String()).Scan(&num); err != nil {
    log.Println(err)
}

使用任何

您也可以使用Postgresql’s ANY,其语法如下:

expression operator ANY (array expression)

使用它,我们的查询可能如下所示:

SELECT COUNT(id) FROM tags WHERE id = ANY('{1,3}'::int[])

在这种情况下,您可以将数组的文本形式声明为参数:

SELECT COUNT(id) FROM tags WHERE id = ANY($1::int[])

这可以简单地像这样构建:

tags := []string{"1","3"}
param := "{" + strings.Join(tags,") + "}"

请注意,在这种情况下不需要检查,因为数组表达式不允许SQL注入(但会导致查询执行错误).

那么完整的代码:

tags := []string{"1","3"}

q := "SELECT COUNT(id) FROM tags WHERE id = ANY($1::int[])"
param := "{" + strings.Join(tags,") + "}"

num := 0
if err := Db.QueryRow(q,param).Scan(&num); err != nil {
    log.Println(err)
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读