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

发布于 2024-10-06 12:01:49 字数 417 浏览 3 评论 0原文

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

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

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

正确的方法是:

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

然后构建参数列表?或者有更好(更正确)的方法来做到这一点?

I have a query that looks like this:

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

I need to be able to parameterize the list in the IN clause to write it as a JDBC PreparedStatement. This list could contain any number of names in it.

Is the correct way to do this:

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

and then build a list of parameters? Or is there a better (more correct) way to do that?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

不顾 2024-10-13 12:01:49

简而言之,你无法开箱即用。然而,有了Spring你就可以做你想做的事。请参阅如何在 (. ..)”通过 Spring JdbcTemplate 的 sql 列表?

In short, you can't out of the box. However, with Spring you can do what you want. See How to generate a dynamic "in (...)" sql list through Spring JdbcTemplate?

泪是无色的血 2024-10-13 12:01:49

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

Standard SQL doesn't allow the IN clause to be parameterized into a single variable -- only dynamic SQL, the SQL query being constructed as a string prior to execution with the comma separated list of values is supported.

夏见 2024-10-13 12:01:49

我也打算研究这个话题。我曾因编写类似的代码而感到内疚,并且从未对它感到 100% 舒服。我想我想在“可变 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 字符串传递给 hibernate 之前,我确实通过验证器运行了它 - 担心注入等。

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

我认为这是笨拙的...在Where 子句中传递这么多ID,但这是需要重构的代码部分。值得庆幸的是,该用例在任何时候都只看到少数 Id 被查询。

I'm going to research this topic, as well. I've been guilty of writing similar code and never felt 100% comfortable with it. I suppose I'd like to find something on "variable SQL parameter lists".

In code, using hibernate, and given a String of comma-delimited order Ids, I've used:

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();

Whereas orderId is really part of a "SELECT x FROM y WHERE IN (%s)".

  1. I did run the orderIds String through a validator prior to passing it to hibernate - being fearful of injections, etc.

  2. Something else that I've been meaning to do is check the limit on SQL parameters and number of characters in the query. I seem to recall hitting a limit somewhere around 2000+ (with MS SQL). That's something to consider if you go with this approach.

I think this is kludgy... to be passing off that many Ids in a Where-clause, but it's a section of code that needs refactoring. Thankfully, the use case has only seen a handful of Ids queried at any one time.

美人骨 2024-10-13 12:01:49

您还可以将查询构建为存储过程,该存储过程将参数化列表作为 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'";

You could also construct your query as a stored procedure that takes the parameterized list as a varchar. For example, in 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

Just make sure your @IN_LIST is formatted as a string that includes the single quotes and commas. For example in java:

String inList = "'smith','jones','brown'";
酒几许 2024-10-13 12:01:49

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

If You use MS SQL Server, try reshape your TSQL to use UDF, Maybe this my post can help You

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文