duanchu7271 2019-05-10 09:16
浏览 144
已采纳

如何在jackc / pgx中使用“ where id in”子句?

Does pgx offer any support for 'where in' clauses? I found in another stackoverflow thread that one should use string concatenation to build the query manually. IMO this is a bit error prone though, as you have to take care of escaping/sql injection and the like on your own.

I also tried to figure it out on my own:

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
}

When I execute this code, I get the following error though:

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

The versions I am using:

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=
  • 写回答

1条回答 默认 最新

  • douyong1850 2019-05-10 13:07
    关注

    As you already know IN expects a list of scalar expressions, not an array, however pgtype.Int4Array represents an array, not a list of scalar expressions.

    "IMO this is a bit error prone though, as you have to take care of escaping/sql injection and the like on your own. "

    Not necessarily, you can loop over your array, construct a string of parameter references, concatenate that to the query and then execute it passing in the array with ....

    var paramrefs string
    ids := []int{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...)
    

    Alternatively you can use ANY instead of IN.

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

    (here you may have to cast the param reference to the appropriate array type, I'm not sure, give it a try without cast, if not ok, try with cast)

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 Vue3 大型图片数据拖动排序
  • ¥15 划分vlan后不通了
  • ¥15 GDI处理通道视频时总是带有白色锯齿
  • ¥20 用雷电模拟器安装百达屋apk一直闪退
  • ¥15 算能科技20240506咨询(拒绝大模型回答)
  • ¥15 自适应 AR 模型 参数估计Matlab程序
  • ¥100 角动量包络面如何用MATLAB绘制
  • ¥15 merge函数占用内存过大
  • ¥15 使用EMD去噪处理RML2016数据集时候的原理
  • ¥15 神经网络预测均方误差很小 但是图像上看着差别太大