Postgresql 数据库片段查询错误“;查询的参数长度必须为0;

Postgresql 数据库片段查询错误“;查询的参数长度必须为0;,postgresql,elixir,ecto,Postgresql,Elixir,Ecto,我试图在building表、jsonbmetadata列和google\u place\u id属性中查询一个json数组,它是一个数组 Elixir给了我一个错误: 以下是片段生成的查询: SELECT b0."id", b0."base_sku", b0."name", b0."logo", b0."email", b0."active", b0."sync", b0."building_group_id", b0."operating_region_id", b0."building_pa

我试图在
building
表、jsonb
metadata
列和
google\u place\u id
属性中查询一个json数组,它是一个数组

Elixir给了我一个错误:

以下是片段生成的查询:

SELECT b0."id", b0."base_sku", b0."name", b0."logo", b0."email", b0."active", b0."sync", b0."building_group_id", b0."operating_region_id", b0."building_package_id", b0."metadata", b0."location", b0."inserted_at", b0."updated_at" FROM "buildings" AS b0 WHERE (b0."metadata"->'google_place_ids' @> '["$1"]') AND (b0."active" = TRUE) ["1234231223123"]
代码如下:

defp query_by_google_place_id(query, google_place_id) do
from(b in query,
    where: fragment("?->'google_place_ids' @> '[\"?\"]'", b.metadata,  ^google_place_id),
    where: b.active == true,
    limit: 1)
end
以下是错误:

[error] #PID<0.1340.0> running Proxy.InstrumentedPlug terminated
Server: localhost:4000 (http)
Request: GET /something/google_place_id/1234231223123
** (exit) an exception was raised:
    ** (ArgumentError) parameters must be of length 0 for query %Postgrex.Query{columns: 
[错误]#运行Proxy.InstrumentedPlug的PID已终止
服务器:本地主机:4000(http)
请求:GET/something/google\u place\u id/12342312223123
**(退出)引发了一个异常:
**(ArgumentError)查询%Postgrex的参数长度必须为0。查询{列:

这不是PostgreSQL理解它的方式。问题是,Ecto的
片段
对SQL(或其他查询语言)一无所知,因此它不再将
视为查询参数,而PostgreSQL将其视为原始字符串
“$1”
。您需要做的是以以下形式直接传递字符串:

fragment("?->'google_place_ids' @> ?", b.metadata, ^"[\"#{google_place_id}\"]")

这样做有效,引用更少,没有括号

defp query_by_google_place_id(query, google_place_id) do
    from(b in query,
        where: fragment("?->'google_place_ids' @> ?", b.metadata, ^google_place_id),
        where: b.active == true,
        limit: 1)
end

这可以防止错误发生,但不会返回任何内容,而且我确信查询应该可以工作,因为它使用
where:fragment(“?->“google\u place\u ids”@>”[\“EXAMPLE\“]”,b.metadata)
其中id直接在查询中。您仍然在搞乱这些东西。这一个有效,因为您直接将数据插入片段,但它不适用于动态插入的数据。如果您熟悉C,那么它将像预处理器宏扩展一样工作:它不会在字符串中展开。