2

プログラムが実行時に行と列の数を取得するテーブルを作成しようとしています。

コードは次のとおりです。

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)

これは、2回目の反復中にsetString行で発生します

4

4 に答える 4

2

動かしてみてください

up1 = con.prepareStatement(sql); 

System.out.println(sql);
于 2012-06-06T21:05:42.097 に答える
1

最初に修正したいのは、Stringインスタンスを変更するときにインスタンスを使用しないでください。Stringインスタンスは不変であり、すでに作成されているインスタンスを変更するとString、新しい変更されたインスタンスが作成され、無料ではありません。StringBuilderこれには、新しいインスタンスを作成せずに変更できるインスタンスメソッドがあるものを使用する必要があります。StringBuilderを変更するときは常に使用することをお勧めしますString。次に、呼び出しcon.prepareStatement(sql)てからそのSQLフィールドを変更します。良くないですよね?したがって、Stringを使用した後でのみ追加してください。

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();
于 2012-06-06T21:08:55.590 に答える
1

確認はしていませんが、アンドリーの答えは正しいと思います。さらに、StringBuilderは軽量であるため、文字列の蓄積にStringBuilderを使用することを検討することをお勧めします。以下のコードを更新しました。

    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();
于 2012-06-06T21:16:26.043 に答える
0

PreparedStatement質問のようなDDLクエリには使用できませんCREATE TABLE

setString()結果の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))

于 2012-06-06T21:16:06.207 に答える