【问题标题】:elixir, ecto: Cannot pass parameter to "CREATE VIEW" raw SQL queryelixir,ecto:无法将参数传递给“CREATE VIEW”原始 SQL 查询
【发布时间】:2020-05-02 08:56:48
【问题描述】:

我们正在构建一个 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 似乎不接受参数。

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

【问题讨论】:

    标签: postgresql elixir ecto postgrex


    【解决方案1】:

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

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

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

    【讨论】:

    • 您好,谢谢您的回答,您能提供一些链接以供将来参考吗?我试图在文档中找到说明这一点,但到目前为止还没有运气
    • 我添加了来源参考。
    猜你喜欢
    • 2018-05-18
    • 1970-01-01
    • 2013-08-02
    • 2015-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多