【问题标题】:How to provide list to epgsql sql where in clause (Erlang)如何为epgsql sql where in子句提供列表(Erlang)
【发布时间】:2021-07-09 18:11:49
【问题描述】:

我找不到正确的语法来向 epgsql:equery 函数提供值列表以在 sql where in 子句中使用。我用谷歌搜索并尝试了几种变体,但都失败了。我的一些尝试如下:

L = [1, 2, 3],
epgsql:equery(Conn, "SELECT $1::integer[]", [L]), % this works
epgsql:equery(Conn, "SELECT * FROM users WHERE id IN $1", [L]), % doesn't work
epgsql:equery(Conn, "SELECT * FROM users WHERE id IN ($1)", [L]), % doesn't work
epgsql:equery(Conn, "SELECT * FROM users WHERE id IN ($1::integer[])", [L]), % doesn't work
epgsql:equery(Conn, "SELECT * FROM users WHERE id IN unnest($1::integer[])", [L]), % doesn't work

这样做的正确方法是什么?

【问题讨论】:

  • 绑定变量是数据本身,因此使用IN( $1 ) 您只传递一个值(在您的情况下为列表类型)。所以从数据库的角度来看它是无效的。您可以尝试execute_batch 或尝试传递一个数组并用= any 包装它,就像回答here 一样。
  • @astentx 嘿,谢谢,它成功了!正确的查询是 epgsql:equery(Conn, "SELECT * FROM users WHERE id = ANY($1::integer[]), [L])。您能否提供您的评论作为答案,以便我接受?

标签: sql postgresql erlang


【解决方案1】:

$1 只传递单个值,因为数据库将绑定变量视为一些原子数据,而不是文本占位符(本质上,绑定变量的值在语句解析完成后使用)。所以在你的情况下,你将一个列表传递给数据库(我假设它被转换为 PG 数组)。

Postgres documentation 说,对于IN,它需要一个标量表达式列表,因此该运算符不会扩展数组。或者,对于数组比较,它建议 ANY/SOMEALL 表达式(分别用于 OR 语义和 AND 语义),您应该在右侧提供一个数组来签入。

由于INexpr = value1 OR expr = value2 OR ... 的简写,您需要将查询转换为:

epgsql:equery(Conn, "SELECT * FROM users WHERE id = ANY($1::int[])", [L])

【讨论】:

    猜你喜欢
    • 2022-01-02
    • 2011-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-15
    • 1970-01-01
    • 2019-06-28
    • 2023-03-06
    相关资源
    最近更新 更多