长生不老药,ecto:无法将参数传递给 "CREATE VIEW" 原始 SQL 查询

elixir, ecto: Cannot pass parameter to "CREATE VIEW" raw SQL query

我们正在构建一个 elixir 应用程序,并使用 ecto 连接到我们的数据库。该应用程序的作用之一是根据我们的事件存储创建报告。我们决定用原始 SQL.

编写这些报告的代码

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

Ecto.Adapters.SQL.query!(
  Repo,
  "CREATE VIEW events_view AS SELECT * FROM events WHERE type = ",
  ["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 = ",
  []
)

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

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

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

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

此限制未记录,但您可以在 src/backend/parser/gram.y 中看到:

PreparableStmt:
            SelectStmt
            | InsertStmt
            | UpdateStmt
            | DeleteStmt                    /* by default all are $$= */
        ;