【问题标题】:Using postgres IN clause in golang在 golang 中使用 postgres IN 子句
【发布时间】:2018-03-23 20:58:37
【问题描述】:

我一直在尝试在 golang 中使用 postgres IN 子句,但一直出错。这是我要执行的查询。

SELECT id1 FROM my_table WHERE type = (an int) AND id2 = (an int) AND id1 IN (list of UUIDs)

我使用这段代码构造了这个查询,但得到了以下错误。

var params []interface{}
inCondition := ""
params = append(params, type)
params = append(params, id2)
for _, id := range id1 {
    params = append(params, id)
    if inCondition != "" {
        inCondition += ", "
    }
    inCondition += "?"
}
query := fmt.Sprintf(`SELECT id1 FROM my_table WHERE type = ? AND id2 = ? AND id1 IN (%s)`, inCondition)
rows, err := db.Query(query, params...)

我得到的查询:

SELECT id1 FROM my_table WHERE type = ? AND id2 = ? AND id1 IN (?, ?, ?)

参数输出:

[]interface {}=[0 7545449 d323f8d5-ab97-46a3-a34e-95ceac2f3a6a d323f8d5-ab97-46a3-a34e-95ceac2f3a6b d323f8d5-ab97-46a3-a34e-95ceac2f3a6d]

错误:

pq: syntax error at or near \"AND\""

我错过了什么?或者,我将如何让它工作? id1 是长度可变的 UUID 切片。

【问题讨论】:

  • 从不使用字符串插值来构建查询。至少在没有仔细引用所有内容的情况下并非如此。这是大规模的 SQL 注入诱饵。请改用绑定参数。例如godoc.org/github.com/lib/pq#Array
  • 你在使用lib/pq吗?对于参数的占位符,请尝试 $1, $2...,而不是 ?
  • 你能显示整个结果查询吗?可能在数据库错误日志中。尝试对 IN 查询使用特殊插值。

标签: postgresql go in-clause


【解决方案1】:

遇到了类似的问题。不记得我到底是在哪里捡到这个的,但我记得在处理整数和字符串类型的数组时仍然遇到问题。我必须做的是拥有一个本地自定义类型并为其返回一个与驱动程序兼容的值。请参阅下面的示例。

// Int64Array is a type implementing the sql/driver/value interface
// This is due to the native driver not supporting arrays...
type Int64Array []int64

// Value returns the driver compatible value
func (a Int64Array) Value() (driver.Value, error) {
    var strs []string
    for _, i := range a {
        strs = append(strs, strconv.FormatInt(i, 10))
    }
    return "{" + strings.Join(strs, ",") + "}", nil
}

强烈建议查看sqlx。编写了一个名为 papergres 的简单 orm 包装器,让我的 go + postgres 生活更轻松:) 试一试。

【讨论】:

    【解决方案2】:

    代替 ?,使用 $1,$2 等作为占位符。

    【讨论】:

    • 是的,Postgres 不接受 ? 占位符。但是,如果您使用sqlx,它允许您在任何语言中使用?(以及命名参数,如:entry_id),然后通过Rebind() 将它们重新映射到相关语言。还有许多其他功能也使 SQL 查询不那么烦人(例如直接扫描到结构中的能力)。
    猜你喜欢
    • 2021-08-28
    • 1970-01-01
    • 2016-10-28
    • 2015-06-29
    • 2013-05-15
    • 2018-06-08
    • 2015-04-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多