有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java IN子句在PreparedStatement上仅返回1行

我正在尝试对工作中的Java程序执行的查询进行优化。 我们必须生成大量数据来测试一个程序,执行查询需要2~3个小时。 今天,程序为我们以前存储在ArrayList上的每个数据创建一个“选择”行。 我试图创建一个包含1000个参数的IN子句的查询。 我已经在这里搜索了一些其他的例子,但是我现在得到的错误与我之前发现的所有错误都不同。 查询字符串创建得非常完美,有1000个“?”我已经设置了1000个带有“for”的参数,正如您在代码中看到的。 但是当我执行查询时,我的ResultSet对象只返回1行,而不是数据库中的1000行。 这里的代码是根据我工作时的代码改编的,由于保密原因,我不能发布原始代码。 工作时是Oracle环境,我家是MySQL环境

希望我解释的方式,有人可以帮助我! 提前谢谢

public ArrayList<String> getDadosIn(ArrayList<String> lista)
{
    PreparedStatement ps = null;
    ResultSet rs = null;
    ArrayList< String > listaDados = new ArrayList< String >();

    Connection conn = ConnectionUtil.getDBConnection();

    try
    {
        StringBuilder query = new StringBuilder();
        Calendar calendar = Calendar.getInstance();
        NumberFormat numberFormat = new DecimalFormat( "00" );

        System.out.println( "Begin query: " +
                            numberFormat.format( calendar.get( Calendar.DAY_OF_MONTH ) ) + "/" + // Dia
                            numberFormat.format( calendar.get( Calendar.MONTH ) + 1 )    + "/" + // Mês
                            calendar.get( Calendar.YEAR )                                + "-" + // Ano
                            numberFormat.format( calendar.get( Calendar.HOUR_OF_DAY ) )  + ":" + // Hora
                            numberFormat.format( calendar.get( Calendar.MINUTE ) )       + ":" + // Minuto
                            numberFormat.format( calendar.get( Calendar.SECOND ) ) );            // Segundo

        query.append( "SELECT ID_CLIENTE FROM CLIENTE WHERE ID_CLIENTE IN (" );

        int i = 1;
        int countAux = 0;
        int countElements = 0;

        for ( int k = 0; k < lista.size(); k++ )
        {
            query.append( "?," );

            countAux++;
            countElements++;

            if(countAux >= 1000)
            {
                query.deleteCharAt( query.length() - 1 );
                query.append( ")" );
                ps = conn.prepareStatement(String.valueOf( query ) );

                for ( int j = 0; j < 1000; j++ )
                {
                    ps.setInt( i++, Integer.parseInt(lista.get(countElements - 1)) );
                }

                rs = ps.executeQuery();

                while ( rs.next() )
                {
                    listaDados.add( rs.getString("id_cliente") );
                }

                ps.close();

                query.delete( 0, query.length() );
                query.append( "SELECT ID_CLIENTE FROM CLIENTE WHERE ID_CLIENTE IN (" );

                i = 1;
                countAux = 0;

                System.out.println( "Registros selecionados: " + countElements + " - lista.size = " + listaDados.size());
            }
        }

        // verifica se ainda há registros para selecionar, uma vez que os selects acima eram executados a cada N vezes
        if(countAux > 0)
        {
            i = 1;

            query.deleteCharAt( query.length() - 1 );
            query.append( ")" );

            ps = conn.prepareStatement(String.valueOf( query ) );

            for ( int j = 0; j < 1000; j++ )
            {
                ps.setInt( i++, Integer.parseInt(lista.get(countElements - 1)) );
            }

            rs = ps.executeQuery();

            while ( rs.next() )
            {
                listaDados.add( rs.getString("id_cliente") );
            }
            ps.close();
        }

        calendar = Calendar.getInstance();

        System.out.println( "End query: " +
                            numberFormat.format( calendar.get( Calendar.DAY_OF_MONTH ) ) + "/" + // Dia
                            numberFormat.format( calendar.get( Calendar.MONTH ) + 1 )    + "/" + // Mês
                            calendar.get( Calendar.YEAR )                                + "-" + // Ano
                            numberFormat.format( calendar.get( Calendar.HOUR_OF_DAY ) )  + ":" + // Hora
                            numberFormat.format( calendar.get( Calendar.MINUTE ) )       + ":" + // Minuto
                            numberFormat.format( calendar.get( Calendar.SECOND ) ) );            // Segundo

        ps.close();
        conn.close();
    }
    catch ( SQLException e )
    {
        e.printStackTrace();
    }

    return listaDados;
}

共 (1) 个答案

  1. # 1 楼答案

    两件事:

    • 在带有整数的for循环中。parseInt(),lista的计数器。get(countElements-1)需要更改为j:

          for ( int j = 0; j < 1000; j++ )
          {
              ps.setInt( i++, Integer.parseInt(lista.get(countElements - 1)) );
          }
      

    改为

                    for ( int j = 0; j < lista.size(); j++ )
                    {
                        ps.setInt( i++, Integer.parseInt(lista.get( j )) );
                    }
    
    • 对于所有For循环,请使用lista。size()作为上限,以避免IndexOutOfBounds异常

                  for ( int j = 0; j < lista.size(); j++ )
                  {
                      ps.setInt( i++, Integer.parseInt(lista.get( j )) );
                  }