2016-09-13 3 views
-1

Я хочу добавить значения в таблицу с динамическими столбцами. Мне удалось создать таблицу с динамическими столбцами, но я не могу понять, как вставлять данные.Как вставить значения в таблицу с динамическими столбцами Jdbc/Mysql

//Create Table 

sql = "CREATE TABLE MyDB.myTable" + 
     "(level INTEGER(255))"; 

     int columnNumber = 5; //Number of columns 

      //Add columns 

     for (i=0;i<columnNumber;i++){ 
       String columnName = "Level_" +i: 
       String sql = "ALTER TABLE MyDB.myTable ADD " + columnName + " INTEGER(30)"; 
    } 

//Insert Data 

//How to insert data dynamically, without knowing the number of columns? 
+0

Зачем использовать sql? Если вы ищете таблицы с динамическими столбцами, вы можете посмотреть что-то вроде MongoDB. – verhie

ответ

2

Вы также можете использовать метаданные базы данных, чтобы получить имена столбцов. Это имеет то преимущество, что вам даже не нужно знать имена столбцов, а они динамически извлекаются в вашем коде.

public static List<String> getColumns(String tableName, String schemaName) throws SQLException{ 

    ResultSet rs=null; 

    ResultSetMetaData rsmd=null; 
    PreparedStatement stmt=null; 
    List<String> columnNames =null; 
    String qualifiedName = (schemaName!=null&&!schemaName.isEmpty())?(schemaName+"."+tableName):tableName; 
    try{ 
     stmt=conn.prepareStatement("select * from "+qualifiedName+" where 0=1"); 
     rs=stmt.executeQuery();//you'll get an empty ResultSet but you'll still get the metadata 
     rsmd=rs.getMetaData(); 
     columnNames = new ArrayList<String>(); 
     for(int i=1;i<=rsmd.getColumnCount();i++) 
      columnNames.add(rsmd.getColumnLabel(i));  
    }catch(SQLException e){ 
     throw e;//or log it 
    } 
    finally{ 
     if(rs!=null) 
      try { 
       rs.close(); 
      } catch (SQLException e) { 
       // TODO Auto-generated catch block 
       throw e 
      } 
     if(stmt!=null) 
      try { 
       stmt.close(); 
      } catch (SQLException e) { 
       // TODO Auto-generated catch block 
       throw e 
      } 
    } 
    return columnNames; 
} 

После того, как у вас есть имена столбцов, вы можете использовать его как обычно (List.size(), конечно, дает число столбцов).

UPDATE:

//I will assume that your values (data to be inserted) is a List of Object types and that it is already populated 



List<Object> data = new ArrayList<>(); 
    //you will populate this list 

    //getting the column names 
    List<String> columnNames = getColumns("MyTable", "MyDB"); 

    String insertColumns = ""; 
    String insertValues = ""; 

    if(columnNames != null && columnNames.size() > 0){ 
     insertColumns += columnNames.get(0); 
     insertValues += "?"; 
    } 


    for(int i = 1; i < columnNames.size();i++){ 
     insertColumns += ", " + columnNames.get(i) ; 
     insertValues += "?"; 
    } 

    String insertSql = "INSERT INTO MyDB.MyTable (" + insertColumns + ") values(" + insertValues + ")"; 

    try{ 
    PrepareStatement ps = conn.prepareStatement(insertSql); 

    for(Object o : data){ 
    ps.setObject(o); //you must pass objects of correct type 
    } 
    ps.execute(); //this inserts your data 
    }catch(SQLException sqle){ 
     //do something with it 
    } 

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

+0

Спасибо, но как я могу вставить данные в конкретную таблицу после того, как я получу количество столбцов? – TedNugent

+0

Я обновил свой ответ. –

+0

Большое спасибо! – TedNugent

0

Если вы знаете, количество столбцов, которые вы хотите вставить, вы можете сделать свою вставку запрос так же, как вы сделали свой CREATE TABLE. Явным назвать столбцы, которые вы хотите добавить свои данные в, и убедитесь, что столбцы оставить пустые разрешено быть пустыми (NULL или значения по умолчанию = 0)

INSERT INTO MyDB.myTable (Level_1, Level_2, ...) VALUES (Val_1, Val_2, ...); 

Альтернативный подход будет хранить каждое вставленное значение отдельный ряд. Таким образом, вы не должны изменять количество столбцов в таблице.

Вам нужна таблица, в которой у вас есть идентификатор для каждой группы значений: - ID - Level - Значение

Вы могли бы иметь отдельную таблицу, где вы можете зарегистрировать каждый ID: - ID (BigInt , автоинкремент, первичный ключ) - информационное поле - отметка времени

Теперь для каждого набора данных, которые вы хотите вставить, сначала нужно вставить уникальный идентификатор. Если вы используете вторую таблицу, вставляя новую строку даст вам новый ID:

INSERT INTO register_table (ID, info, timestamp) VALUES (NULL, 'some info', NOW()); 

Это даст вам новый идентификатор (last_inserted_id). С этим идентификатором Теперь вставить все значения в другой таблице:

for(i=0i<columnNumber;i++){ 
    "INSERT INTO _table (ID, Level, _Value) VALUES ("+ the_ID +", "+ i +", "+ the_VALUE +");"; 
} 

Если вы хотите получать данные:

"SELECT Level, _Value FROM _table WHERE ID="+ the_ID +" ORDER BY Level;"; 
+0

Проблема в том, что я не знаю, сколько столбцов я хочу вставить. Он варьируется в зависимости от пользовательских настроек и не фиксируется. – TedNugent

+0

, в этом случае я бы предложил другой подход: сделайте это строками вместо столбцов: введите таблицу с тремя столбцами: ID, Level, Value. Вы можете вставить все нужные данные и до тех пор, пока у вас одинаковый идентификатор для каждой транзакции. – verhie

+0

Не могли бы вы объяснить мне подробно? – TedNugent

Смежные вопросы