Создание таблиц в базе данных Oracle JDBC

У меня проблема с созданием таблиц контроллером JDBC в базе данных Oracle. Когда я создаю таблицу "creata table....", это нормально. Таблица create, и я вижу эту таблицу разработчиком SQL. У меня есть метод, чтобы проверить, существует ли таблица с таким именем, и она работает хорошо. Поэтому, когда я создаю таблицу (я тоже пытаюсь сделать фиксацию - не помогаю), таблица появляется в SQL-разработчике, но когда я проверяю мой метод, если эта таблица существует, я получаю "false" (не существует), когда я перезапускаю базу данных и снова запустите, мой метод вернет "true". Я думаю, что это проблема с сеансом, но я не понимаю, как с этим справиться.

enter code here public void prepStatExecuteCreateTable(String name){
 String createTable= "Create table "+ name +" (ID NUMBER(*, 0) NOT NULL PRIMARY KEY, CZAS NUMBER(*, 0) NOT NULL, OTWARCIE NUMBER(6, 2) NOT NULL , MAX_KURS NUMBER(6, 2) NOT NULL , MIN_KURS NUMBER(6, 2) NOT NULL , ZAMKNIECIE NUMBER(6, 2) NOT NULL , VOLUMEN NUMBER(*, 0) NOT NULL , FOREIGN KEY(czas) references CZAS(ID))";
 PreparedStatement ps=null;
 try{
 ps = returnConnection().prepareStatement(createTable);

 }catch(SQLException e){
 System.out.println("Error with preperadStatement(create table): "+ e.getMessage());
 }

 try{
 ps.execute();

 returnConnection().commit();
 ps.close();
 closeConnection();
 }
 catch(SQLException e){
 System.out.println("Error with execute: "+ e.getMessage());
 }

}


public boolean ifExistTable(String tablename) throws SQLException{
 String sql = "Select TABLE_NAME from user_tables where table_name='"+tablename.toUpperCase()+"' "; 
 System.out.println(sql);
 ResultSet rs =null;
 Statement ps = null;
 try{
 ps = returnConnection().createStatement();
 }catch(SQLException e){
 System.out.println("Error with preperadSatement(checking): "+ e.getMessage());
 }
 try{
 rs=ps.executeQuery(sql);
 while (rs.next()){
 System.out.println (rs.getString(1)); // Print col 1
 if(rs.getString(1).equals(tablename)){
 return true;
 }
 }
 }
 catch(SQLException e){
 System.out.println("Error with executing checking " +e.getMessage()+ " " + e.getStackTrace());
 }
 ps.close();
 return false;
}

так я использую в методе Main: (condDB - это объект, который имеет вышеописанные методы)

enter code here String table_name="BBB";
 System.out.println(conDB.ifExistTable(table_name));
 conDB.prepStatExecuteCreateTable(table_name);

поэтому, если я запускаю сначала, я получаю сообщение "false" (таблица не существует) и создается (проверка разработчиком SQL, таблица с именем "BBB" появляется), когда я запускаю во второй раз, я получаю сообщение "false" и сообщение об ошибке со второго method: Ошибка при выполнении: ORA-00955: имя уже используется существующим объектом

2 ответа

1) Ваша функция ifExistTable действительно должна использовать переменные связывания, а не строить оператор SQL с помощью конкатенации строк, если только для предотвращения атак SQL-инъекций.

2) Функция ifExistTable запускает запрос, в котором используется значение верхнего регистра переданного имени tablename. Но тогда, когда вы извлекаете данные из rs, вы делаете чувствительный к регистру сопоставление с rs.getString(1).equals(tablename). Как минимум, это должно быть equalsIgnoreCase. Но вообще не должно быть никакого сравнения вообще в Java, поскольку ваш SQL-оператор уже делает это. Если ResultSet имеет строку, таблица существует (или вы можете написать запрос как COUNT(*) и проверить, имеет ли строка, которая возвращается, значение "1").


Возможно, когда вы создали свою хранимую процедуру внутри пакета, вы не закрыли ее с помощью '/'

...
END;
/

поэтому соединение застряло, и ресурс не освобождается, чтобы использоваться другим запросом (что на самом деле является другим логическим соединением). фиксация не будет работать, поскольку вы выполняете предложение DDL, которое может заботиться о том, чтобы совершить хехех

licensed under cc by-sa 3.0 with attribution.