长生不老药,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 的限制:您只能在 SELECT
、INSERT
、UPDATE
和 DELETE
语句中使用参数。对于所有其他语句,您必须通过在字符串中包含值来构造语句。谨防 SQL 注入!
此限制未记录,但您可以在 src/backend/parser/gram.y
中看到:
PreparableStmt:
SelectStmt
| InsertStmt
| UpdateStmt
| DeleteStmt /* by default all are $$= */
;
我们正在构建一个 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 的限制:您只能在 SELECT
、INSERT
、UPDATE
和 DELETE
语句中使用参数。对于所有其他语句,您必须通过在字符串中包含值来构造语句。谨防 SQL 注入!
此限制未记录,但您可以在 src/backend/parser/gram.y
中看到:
PreparableStmt:
SelectStmt
| InsertStmt
| UpdateStmt
| DeleteStmt /* by default all are $$= */
;