2017-01-08 3 views
0

Я пытаюсь сделать ТАБЛИЦУ COMPB эквивалентным TABLE COMPA с помощью операций обновления и удаления в таблице COMPB на основе таблицы COMPA. Код работает отлично, создавая правильный SQL. Проблема в том, что момент я ставлю оператор выполнения, как показано ниже, в то время как цикл завершает первую итерацию. Невозможно понять это поведение ResultSet в java. Любая помощь здесь? Где я ошибаюсь?While Loop Terminating after ResultSet.execute

//Comparision between Minus Table(seta) and COMPB (setc) 
     //ID Contains Primary Key of COMPB Table 
     ResultSet seta=stmt.executeQuery("select * from COMPA minus select * from COMPB"); 


     while(seta.next()) 
     { 
      String insert=""; 
      String update=""; 
      boolean contains=ArrayUtils.contains(ID, seta.getInt(1)); 

      if (contains==true) 
      { 
       update="Update COMPB SET COMPB.EMPNAME='"+seta.getString(2)+"',COMPB.EMAILID='"+seta.getString(3)+"' where "+seta.getInt(1)+"=COMPB.EMPID"; 
       stmt.executeUpdate(update); 
       System.out.println(update); 
      } 
      else 
      { 
      insert="Insert INTO COMPB values ("+seta.getInt(1)+" , '"+seta.getString(2)+"' , '"+seta.getString(3)+"')"; 
       stmt.executeUpdate(insert); 
       System.out.println(insert); 
      } 


     } 
+0

Я полагаю, вам не нравится повторное использование 'stmt' для последующих вызовов' executeUpdate() ', но какая отладка вы сделали? Что получает исходный запрос, если вы запускаете его вручную - при условии, что все изменения во всех сеансах совершены? Кроме того, зачем использовать циклы вместо одного оператора слияния; и если вы должны использовать циклы, почему вы не используете подготовленные операторы и связываете переменные? –

+0

Спасибо Алекс. Проблема повторного использования stmt внутри цикла была проблемой. Я еще не понял, как это может разрушить цикл while. Но сейчас я исправил это. –

+0

Я настоятельно рекомендую вам прекратить соединять значения в строку запроса, вместо этого используйте подготовленный оператор с записями параметров. Ваш текущий код небезопасен и уязвим для SQL-инъекции. –

ответ

1

Там могут быть две причины для этого:

  • Повторное использование же stmt объекта: Результат установить объект сопоставляются с утверждением, что возвращенного его (через executeQuery метод) и повторного использования тот же объект-оператор в середине итерации сделает недопустимый результат. Вы должны создать новый объект оператора и выполнить с ним эти запросы.
  • Использование CONCUR_READ_ONLYresultSet (по умолчанию): Here's Документация Oracle по набору результатов. По умолчанию он не модифицируется. Возможно, вам придется использовать набор результатов CONCUR_UPDATABLE, если записи необходимо изменить. Here - пример этого.
+0

Спасибо Даршан. –

+0

_ «Возможно сделать недопустимый результат» _, попробуйте ** must ** сделать недействительным; это требование спецификации JDBC. –

+0

@MarkRotteveel исправлено, спасибо, что указали его. –

1

Невозможно понять это поведение ResultSet в java.

Вы используете один и тот же экземпляр PreparedStatementstmt выполнить обновление:

ResultSet seta=stmt.executeQuery("select * from COMPA minus select * from COMPB"); 

while(seta.next()){ 
    ... 

    update="Update COMPB SET COMPB.EMPNAME='"+seta.getString(2)+"',COMPB.EMAILID='"+seta.getString(3)+"' where "+seta.getInt(1)+"=COMPB.EMPID"; 
    stmt.executeUpdate(update); 
    System.out.println(update); 
    ... 
    } 

Ваш ResultSet seta приходит из PreparedStatementstmt экземпляра.
Так что я предполагаю, что вызов другого метода execute в экземпляре PreparedStatement имеет побочный эффект для ранее объекта ResultSet, возвращаемого экземпляром PreparedStatement.

Чтобы выполнить другие запросы, вы должны создать новый экземпляр PreparedStatement.

+0

В показанном коде используется обычный объект 'Statement', но суть вашего ответа правильная. –

+0

@Mark Rotteveel Действительно. Спасибо. – davidxxx

+0

@ Хари Прасад Добро пожаловать :) – davidxxx

0

Согласно приведенным ниже предложениям, я изменил цикл, создав подготовленные объекты.

  while(seta.next()) 
     { 

      boolean contains=ArrayUtils.contains(ID, seta.getInt(1)); 

      if (contains==true) 
      { 


       PreparedStatement update_stmt =con.prepareStatement("Update COMPB SET COMPB.EMPNAME=?,COMPB.EMAILID=? where COMPB.EMPID=?"); 
       update_stmt.setInt(3,seta.getInt(1)); 
       update_stmt.setString(1,seta.getString(2)); 
       update_stmt.setString(2,seta.getString(3)); 
       int k=update_stmt.executeUpdate(); 
       System.out.println(k+" records updated"); 

      } 
      else 
      { 

      PreparedStatement insert_stmt =con.prepareStatement("insert into COMPB values(?,?,?)"); 
      insert_stmt.setInt(1,seta.getInt(1)); 
      insert_stmt.setString(2,seta.getString(2)); 
      insert_stmt.setString(3,seta.getString(3)); 
      int k=insert_stmt.executeUpdate(); 
      System.out.println(k+" records inserted"); 

      } 


     }