是否可以在 sql 参数中传递和使用 sql?

Posted

技术标签:

【中文标题】是否可以在 sql 参数中传递和使用 sql?【英文标题】:Is it possible to pass and use sql inside a sql parameter? 【发布时间】:2021-05-27 19:27:39 【问题描述】:

我正在处理一个由多个服务使用的查询,但返回的结果数量因过滤而异。

为了避免复制和粘贴查询,我想知道是否可以将一段 sql 传递到 sql 参数中,它会起作用吗?我也愿意接受替代解决方案。

示例:

MapSqlParameterSource parameters = new MapSqlParameterSource();
parameters.addValue("filter", "and color = blue");

namedParameterJdbcTemplate.query(“select * from foo where name = 'Joe' :filter”, parameters, new urobjRowMapper());

【问题讨论】:

这样不行,因为参数不是sql语句的一部分,在解析时也不会被解析。它们替换了数据,因此这种方法只能使用动态 SQL。但是如果你不能完全控制参数的内容,这可能会导致 SQL 注入 这是灾难的秘诀。我记得早在 2010 年,一位开发人员提出了类似的要求。他希望在应用程序中有一个“秘密页面”,我们可以在其中键入任何 SQL 语句,应用程序就会运行它:“调试问题会更容易”,他说。一年后他被解雇了。 我想补充一点,这些过滤器将是常量,所以我不担心 sql 注入。 【参考方案1】:

让调用者将 SQL 传递给您的程序是非常危险和脆弱的,因为它会让您面临 SQL 注入 - 参数正是要防止的问题。

更好的方法是在查询中预先编码过滤器,并通过特殊的“选择器”参数保护它们:

SELECT *
FROM foo
WHERE name='Joe' AND
(
    (:qselect = 1 AND color='blue')
OR  (:qselect = 2 AND startYear = 2021)
OR  (:qselect = 3 AND ...)
)

【讨论】:

我想补充一点,这些过滤器将是常量,所以我不担心 sql 注入。 @Aloha_Scope 如果过滤器是常量,则没有理由将它们保留在查询之外。在查询中列出它们,并使用选择器来选择实际使用的。 没关系。我应该提到,除了询问它是否应该工作之外,我对其他解决方案持开放态度。

以上是关于是否可以在 sql 参数中传递和使用 sql?的主要内容,如果未能解决你的问题,请参考以下文章

SQL 将表作为参数传递?

传递键值对是不是也可以防止 SQL 注入攻击?

使用“IN”命令将数组作为要在 SQL 查询中使用的参数传递

在sql语句中,怎样将参数做为表名传递到查询语句中

Oracle PL/SQL 传递行类型作为构造函数参数

为一个 SQL 参数传递多个值