0

我们正在构建一个 elixir 应用程序,并使用 ecto 连接到我们的数据库。应用程序的角色之一是根据我们的事件存储创建报告。我们决定用原始 SQL 编写这些报告的代码。

我需要使用一些参数创建一个临时视图。考虑以下代码:

Ecto.Adapters.SQL.query!(
  Repo,
  "CREATE VIEW events_view AS SELECT * FROM events WHERE type = $1",
  ["hello world"]
)

# This will fail with the following error:
# (ArgumentError) parameters must be of length 0 for query [...]

上面的代码,只有一个参数,不起作用(显然在 ecto/postgrex 级别)。但是,删除参数会使 postgres 级别的查询失败。

Ecto.Adapters.SQL.query!(
  Repo,
  "CREATE VIEW events_view AS SELECT * FROM events WHERE type = $1",
  []
)

# And this will fails because Postgres complains about a missing parameter
# (Postgrex.Error) ERROR 42P02 (undefined_parameter) there is no parameter $1

我已经使用这种方式为大量查询传递参数,包括 SELECT 和 CREATE TABLE 查询。然而,出于某种原因, CREATE VIEW 似乎不接受参数。

知道如何解决这个问题吗?

4

1 回答 1

1

这是 PostgreSQL 的限制:您只能在SELECTINSERT和语句UPDATE中使用参数。DELETE对于所有其他语句,您必须通过在字符串中包含值来构造语句。谨防 SQL 注入!

此限制未记录在案,但您可以在以下位置看到src/backend/parser/gram.y

PreparableStmt:
            SelectStmt
            | InsertStmt
            | UpdateStmt
            | DeleteStmt                    /* by default all are $$=$1 */
        ;
于 2020-01-15T16:37:23.460 回答