database - 如何在 jackc/pgx 中使用 'where id in' 子句?

标签 database postgresql go pgx

pgx 是否支持“where in”子句?我在另一个 stackoverflow 线程中发现应该使用字符串连接来手动构建查询。 IMO 这有点容易出错,因为你必须自己处理转义/sql 注入(inject)等。

我也试着自己弄明白了:

const updatePurgedRecordingsStmt = "update recordings set status = 'DELETED', deleted = now() where status <> 'DELETED' and id in ($1);"

func (r *Repository) DeleteRecordings() error {
    pool, err := r.connPool()
    if err != nil {
        return errors.Wrap(err, "cannot establish connection")
    }
    pgRecIds := &pgtype.Int4Array{}

    if err := pgRecIds.Set([]int32{int32(1), int32(2)}); err != nil {
        return errors.Wrap(err, "id conversion failed")
    }
    if _, err = pool.Exec(updatePurgedRecordingsStmt, pgRecIds); err != nil {
        return errors.Wrap(err, "update stmt failed")
    }
    return nil
}

当我执行这段代码时,我得到了以下错误:

ERROR: incorrect binary data format in bind parameter 1 (SQLSTATE 22P03)

我使用的版本:

Postgres:

db=> SELECT version();
                                              version
-----------------------------------------------------------------------------------------------------------
 PostgreSQL 9.6.11 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.8.2 20140120 (Red Hat 4.8.2-16), 64-bit
(1 row)

PGX:

github.com/jackc/fake v0.0.0-20150926172116-812a484cc733 h1:vr3AYkKovP8uR8AvSGGUK1IDqRa5lAAvEkZG1LKaCRc=
github.com/jackc/fake v0.0.0-20150926172116-812a484cc733/go.mod h1:WrMFNQdiFJ80sQsxDoMokWK1W5TQtxBFNpzWTD84ibQ=
github.com/jackc/pgx v3.3.0+incompatible h1:Wa90/+qsITBAPkAZjiByeIGHFcj3Ztu+VzrrIpHjL90=
github.com/jackc/pgx v3.3.0+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I=
github.com/lib/pq v1.0.0 h1:X5PMW56eZitiTeO7tKzZxFCSpbFZJtkMMooicw2us9A=
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=

最佳答案

如您所知,IN 需要一个标量表达式 列表,而不是一个数组,但是 pgtype.Int4Array 表示一个数组,不是标量表达式的列表。

“IMO 虽然这有点容易出错,因为您必须自己处理转义/sql 注入(inject)等。”

不一定,您可以遍历您的数组,构造一个参数引用字符串,将其连接到查询,然后使用 ... 传入数组执行它。

var paramrefs string
ids := []interface{}{1,2,3,4}
for i, _ := range ids {
    paramrefs += `$` + strconv.Itoa(i+1) + `,`
}
paramrefs = paramrefs[:len(paramrefs)-1] // remove last ","

query := `UPDATE ... WHERE id IN (` + paramrefs + `)`
pool.Exec(query, ids...)

或者,您可以使用 ANY 而不是 IN

ids := &pgtype.Int4Array{}
ids.Set([]int{1,2,3,4})
query := `UPDATE ... WHERE id = ANY ($1)`
pool.Exec(query, ids)

(这里你可能必须将参数引用转换为适当的数组类型,我不确定,试试不转换,如果不行,尝试转换)

关于database - 如何在 jackc/pgx 中使用 'where id in' 子句?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56074423/

相关文章:

PostgreSQL 查询 : Column Sum for the latest available date of each month

http - Golang 相当于 java servlet 过滤器

dictionary - 如何正确初始化一片 map

Python Pony ORM 一次插入多个值

mongodb - 我应该选择什么 : MongoDB/Cassandra/Redis/CouchDB?

javascript - 无法使用查询从 Cloud Firestore 检索数据

php - 实时多人游戏技术

c - PostgreSQL C 函数获取参数 varchar 类型

sql - 如何比较 PostgreSQL 中相同条目的两行?

戈朗 : question about interface implementation inheritance