我正在尝试在工作中优化在Java程序上执行的查询。 我们必须生成大量数据来测试程序,并且执行查询需要2到3个小时。 今天,程序为我们先前存储在ArrayList上的每个数据创建一个“SELECT”行。 我正在尝试使用IN子句创建一个查询,其中包含1000个参数。 我已经在这里搜索了一些其他的例子,但是我现在得到的错误与我迄今为止发现的所有错误不同。 查询字符串是否完美创建,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;
}
答案 0 :(得分:0)
一些事情:
在使用Integer.parseInt()的for循环中,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 )) );
}