如何使用WHERE x IN子句为PreparedStatement编写SQL?

时间:2010-12-07 21:29:23

标签: sql jdbc prepared-statement

我有一个如下所示的查询:

SELECT last_name,
       first_name,
       middle_initial
FROM   names
WHERE  last_name IN ('smith', 'jones', 'brown')

我需要能够参数化IN子句中的列表,将其写为JDBC PreparedStatement。该列表中可以包含任意数量的名称。

这是正确的方法:

SELECT last_name,
       first_name,
       middle_initial
FROM   names
WHERE  last_name IN (?)

然后构建一个参数列表?或者有更好(更正确)的方法吗?

5 个答案:

答案 0 :(得分:2)

简而言之,你无法开箱即用。但是,使用Spring,您可以做您想做的事。见How to generate a dynamic "in (...)" sql list through Spring JdbcTemplate?

答案 1 :(得分:0)

标准SQL不允许将IN子句参数化为单个变量 - 仅动态SQL,支持在使用逗号分隔的值列表执行之前构造为字符串的SQL查询。

答案 2 :(得分:0)

我也将研究这个话题。我一直因编写类似的代码而感到愧疚,并且从未对此感到满意。我想我想在“变量SQL参数列表”上找到一些东西。

在代码中,使用hibernate,并给出一个逗号分隔的命令ID字符串,我用过:

Session s = getSession();
Criteria crit = s.createCriteria(this.getOrderListingClass());
crit.add(Expression.sql(String.format("{alias}.orderId in (%s)", orderIds)));
crit.add(Expression.eq("status", OrderInfo.Order_STATUS_UNFILLED));
orders = crit.list();

而orderId实际上是“SELECT x FROM y WHERE IN(%s)”的一部分。

  1. 我确实在将它传递给休眠之前通过验证器运行了orderIds字符串 - 担心注入等等。

  2. 我一直想做的其他事情是检查SQL参数的限制和查询中的字符数。我似乎记得在2000+左右达到限制(使用MS SQL)。如果你采用这种方法,那就要考虑了。

  3. 我认为这很糟糕......在Where子句中传递了许多ID,但它是需要重构的一段代码。值得庆幸的是,用例在任何时候都只看到过少量的Ids。

答案 3 :(得分:0)

您还可以将查询构造为将参数化列表作为varchar的存储过程。例如,在sql server中:

  CREATE PROCEDURE dbo.[procedure_name]

        @IN_LIST VARCHAR(MAX)
    AS
    BEGIN

        DECLARE @SQL VARCHAR(MAX)
        SET @SQL = '
            SELECT last_name,
                first_name,
                middle_initial
            FROM names
            WHERE  last_name IN (' + @IN_LIST + ')'

        EXECUTE(@SQL)
    END

只需确保您的@IN_LIST格式化为包含单引号和逗号的字符串。例如在java:

String inList = "'smith','jones','brown'";

答案 4 :(得分:0)

如果您使用MS SQL Server,请尝试重塑您的TSQL以使用UDF,也许this我的帖子可以帮助您