2012-06-06 2 views
2

Я пытаюсь создать таблицу, в которой программа получает количество строк и столбцов во время выполнения.Ошибка передачи команды SQL через подготовленный оператор через jdbc

Вот код:

String sql = 
    "CREATE TABLE if not exists itemset (?"; 
up1 = con.prepareStatement(sql); 
for(int j=1; j < ccolumns; j++) { 
    sql += ",?"; 
} 
sql += ")"; 
System.out.println(sql); 
for(int j=1; j < ccolumns+1; j++) { 
    System.out.println(j); 
    up1.setString(j, "item"+j+" TINYINT(10)"); 
} 
up1.executeQuery(); 

Ошибка

Parameter index out of range (2 > number of parameters, which is 1)

Это происходит в SetString линии во второй итерации

+0

Возможно, вам следует называть «подготовить» * после того, как * вы закончите строить строку SQL;)? – paulsm4

+0

PreparedStatement не следует использовать для CREATE TABLE sql. –

ответ

0

PreparedStatement не могут быть использованы для DDL запросов как CREATE TABLE в вопросе.

Значения, переданные в setString(), получают escape-код в результате SQL, что приводит к недействительному запросу, отправленному в базу данных.

Когда только число столбцов дается, просто создать CREATE TABLE заявление (используйте StringBuilder, как другие предложили) и выполнить его с простым Statement, нет необходимости в PreparedStatement:

String getCreateTableSql(int columns) { 
    StringBuilder sql = new StringBuilder("CREATE TABLE IF NOT EXISTS itemset ("); 
    for (int i = 0; i < columns; i++) { 
    if (i > 0) { 
     sql.append(", "); 
    } 
    sql.append("item").append(i + 1).append(" TINYINT(10)"); 
    } 
    sql.append(")"); 
    return sql.toString(); 
} 

Для 4 колонны, этот выход будет:

CREATE TABLE IF NOT EXISTS itemset (item1 TINYINT(10), item2 TINYINT(10), item3 TINYINT(10), item4 TINYINT(10))

+0

Да, простой оператор работает, но я хотел попробовать заявление о подготовке. – StrawhatLuffy

2

Try двигаться

up1 = con.prepareStatement(sql); 

После

System.out.println(sql); 
+0

Это действительно решена ранее проблемы, но теперь она дает новую проблему Для ccolumns вход 5, оператор SQL, как представляется, были изменены на «» ITEM1 TINYINT (10) «» ITEM2 TINYINT (10) ',' item3 TINYINT (10) ',' item4 TINYINT (10) ',' вместо 4 должно быть 5 из них (вторая петля повторяется 5 раз) – StrawhatLuffy

1

Первое, что вы хотите, чтобы исправить это, пожалуйста, не используйте String случай, когда вы хотите, чтобы изменить его. String intance неизменен, и при изменении уже созданного String создается новый модифицированный экземпляр и он не является бесплатным. Для этого необходимо использовать StringBuilder, которые имеют методы экземпляра, которые позволяют изменять его без необходимости создания нового экземпляра. Я рекомендую вам всегда использовать StringBuilder при изменении String. и во-вторых, вы вызываете con.prepareStatement(sql), а затем вы изменяете его поле sql. это не хорошо, не так ли? Так что добавьте его только после работы со строкой.

String sql = 
    "CREATE TABLE if not exists itemset (?"; 
for(int j=1; j < ccolumns; j++) { 
    sql += ",?"; 
} 
sql += ")"; 
System.out.println(sql); 
up1 = con.prepareStatement(sql); 
for(int j=1; j < ccolumns+1; j++) { 
    System.out.println(j); 
    up1.setString(j, "item"+j+" TINYINT(10)"); 
} 
up1.executeQuery(); 

Вы не можете назвать prepareStatement с данной String, а затем изменить его.


Но более чище и быстрее, попробуйте сделать это как этот

StringBuilder sqlStatement = new StringBuilder(
     "CREATE TABLE if not exists itemset (?"); 
    for(int j=1; j < ccolumns; j++) { 
     sqlStatement.append(",?"); 
    } 
    sqlStatement.append(")"); 
    up1 = con.prepareStatement(sqlStatement.toString()); 
    for(int j=1; j < ccolumns+1; j++) { 
     System.out.println(j); 
     up1.setString(j, "item"+j+" TINYINT(10)"); 
    } 
    up1.executeQuery(); 
+0

@PhilippReichart извините, плохо замените сразу, я увидел это, исправлено. – Sajmon

+0

Ошибка заключается в том, чтобы дать предварительную подготовку перед строкой, используя StringBuilder, который она по-прежнему дает проблему, о которой я упомянул в ответ на andriy, anyways я не знал abt StringBuilder спасибо – StrawhatLuffy

1

Хотя я не проверил это, я считаю, что ответ Андрей является правильным. Кроме того, вы можете рассмотреть возможность использования StringBuilder для накопления String, поскольку они более легкие. Обновленный код ниже.

StringBuilder sql = new StringBuilder("CREATE TABLE if not exists itemset (?"); 
    for (int j = 1; j < ccolumns; j++) { 
     sql.append(",?"); 
    } 
    sql.append(")"); 
    System.out.println(sql.toString()); 
    up1 = con.prepareStatement(sql.toString()); 
    for (int j = 1; j < ccolumns + 1; j++) { 
     System.out.println(j); 
     up1.setString(j, "item" + j + " TINYINT(10)"); 
    } 
    up1.executeQuery(); 
Смежные вопросы