【问题标题】:How to pass List in sql query如何在sql查询中传递List
【发布时间】:2023-03-16 21:19:01
【问题描述】:

我有一些值(例如1, 2, 3),我想将该列表传递给 SQL 查询:

"select name from tbl where id in" + list 

我怎样才能做到这一点?

【问题讨论】:

  • 你用什么来构建你的sql?

标签: java sql


【解决方案1】:

你必须把你的列表直接放到sql语句中

示例:

String sql="select name from tbl where id in ("+StringUtils.join(list, ',')+")";
Statement st=connection.createStatement();
st.execute(sql);

【讨论】:

  • 在 Java 8 中,您可以使用 String.join(",", list),但是此解决方案不适用于字符串参数。
  • 此代码存在安全问题。因为值没有转义,所以可以进行 SQL 注入。
【解决方案2】:

我在您对评论的回复中看到您正在使用 HQL。如果是这种情况,Hibernate 人员会为您简化这一操作,只需在查询中指定:

where id in (:ids)

然后使用setParameterList("ids", list) 传递您的列表。 Hibernate 会为你做所有的扩展!

【讨论】:

    【解决方案3】:

    SQL 语法是:

    select name from tbl where id in (1,2,3)
    

    您所要做的就是构建以逗号分隔的项目列表并将其插入到字符串中。

    哦,还有强制性的 sql 字符串构建警告:不要!

    【讨论】:

      【解决方案4】:

      这取决于你如何构建你的 sql。如果您自己构建它(坏主意),您需要让 sql 看起来像 -

      ... where id in (1,2,3)...

      由于您在评论中指定了休眠 hql,因此类似于 -

      Query query = session.createSQLQuery("from User where id in :ids ");
      query.setParameter("ids", idsList);
      List list = query.list();
      

      应该让你开始。注意User 是您映射到要查询的表的对象的名称。

      【讨论】:

      • @vinay,通过编辑在问题中发布失败的代码和堆栈跟踪
      【解决方案5】:

      将列表作为逗号分隔列表传入,并使用 split 函数将其拆分为临时表变量。

      CREATE FUNCTION dbo.Split (@sep char(1), @s varchar(512))
      RETURNS table
      AS
      RETURN (
          WITH Pieces(pn, start, stop) AS (
            SELECT 1, 1, CHARINDEX(@sep, @s)
            UNION ALL
            SELECT pn + 1, stop + 1, CHARINDEX(@sep, @s, stop + 1)
            FROM Pieces
            WHERE stop > 0
          )
          SELECT pn,
            SUBSTRING(@s, start, CASE WHEN stop > 0 THEN stop-start ELSE 512 END) AS s
          FROM Pieces
        )
      

      【讨论】:

      • 谈谈用战术核武器打兔子……或者使用微软的报告服务器,基本上是一样的。
      • 我想我把这个问题误解为“如何将这个列表传递给存储过程”。我的错。
      【解决方案6】:

      String sqlQuery = "从 tbl 中选择名称,其中 id 在" + sqlFormatedList(list);

      private String sqlFormatedList(List<Integer> list){
       StringBuilder sb = new StringBuilder();
       sb.append("(");
       for (Integer i : list){
         sb.append(i+",");
       }
       sb.deleteCharAt(sb.length() -1);
       sb.append(")");
       return sb.toString();
      }
      

      【讨论】:

      • 现在我得到 [1,2,3] 作为 (123) ,所以如何用逗号分隔字符串,我正在与 id 进行比较,id 是整数,但“sb”是字符串,那么如何制作呢
      • 对不起,我会在 1 分钟内为您修好,所以修好了。
      【解决方案7】:

      使用 java 8 及以上版本:

      String inClause = list.stream().map(id-> String.valueOf(id)).collect(toStringJoiner(","));
      String sql = "select name from tbl where name in (" + inClause + ")";
      

      【讨论】:

        【解决方案8】:
        private static String sqlFormatedList(List<String> list){
             StringBuilder sb = new StringBuilder();
             sb.append("('");
             for (String i : list){
               sb.append(i+"','");
             }
             sb.deleteCharAt(sb.length() -1);
             sb.deleteCharAt(sb.lastIndexOf(","));
             sb.append(")");
             return sb.toString();
            }
        

        【讨论】:

        • 完全易受 SQL 注入攻击,并且不考虑带单引号的字符串。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-12-22
        • 2013-11-04
        相关资源
        最近更新 更多