【问题标题】:Insert query in mysql using metadata使用元数据在 mysql 中插入查询
【发布时间】:2014-11-25 09:54:17
【问题描述】:

我有一个由表的列名组成的列表

String tableName="employee";
ResultSet rs = Statement.executeQuery("SELECT * FROM"+tableName);
    ResultSetMetaData   rmd = rs.getMetaData();
        int columnCount = rmd.getColumnCount();
        List columnsList = new ArrayList();
        for (int i = 1; i <= columnCount; i++) {
            columnsList.add(rmd.getColumnName(i));
        }

列出值=[一些值];

now columnsList =[emp_id, name, salary, department];

现在我想使用这些列名编写插入查询。但我不想硬编码列名,我想从列表中获取这些名称并将它们传递给列名,例如

   String subQuery= "insert into"+tableName+......here i want to get column names from list.....+.......here values from another list......;

有没有办法得到这个

【问题讨论】:

  • "FROM" 和 tableName ResultSet 之间需要空格 rs = Statement.executeQuery("SELECT * FROM "+tableName);

标签: java mysql jdbc sql-insert


【解决方案1】:

一直在谷歌上搜索我的#@$,以寻找代码运送以动态生成 JDBC 插入语句表单元数据。参考generateInsertStatements()

private static void generateInsertStatements(Connection conn, String tableName)
throws Exception {
    log("Generating Insert statements for: " + tableName);
    Statement stmt = conn.createStatement();
    ResultSet rs = stmt.executeQuery("SELECT * FROM " + tableName); 
    ResultSetMetaData rsmd = rs.getMetaData();
    int numColumns = rsmd.getColumnCount();
    int[] columnTypes = new int[numColumns];
    String columnNames = "";
    for (int i = 0; i < numColumns; i++) {
        columnTypes[i] = rsmd.getColumnType(i + 1);
        if (i != 0) {
            columnNames += ",";
        }
        columnNames += rsmd.getColumnName(i + 1);
    }

    java.util.Date d = null; 
    PrintWriter p = new PrintWriter(new FileWriter(tableName + "_insert.sql"));
    p.println("set sqlt off");
    p.println("set sqlblanklines on");
    p.println("set define off");
    while (rs.next()) {
        String columnValues = "";
        for (int i = 0; i < numColumns; i++) {
            if (i != 0) {
                columnValues += ",";
            }

            switch (columnTypes[i]) {
                case Types.BIGINT:
                case Types.BIT:
                case Types.BOOLEAN:
                case Types.DECIMAL:
                case Types.DOUBLE:
                case Types.FLOAT:
                case Types.INTEGER:
                case Types.SMALLINT:
                case Types.TINYINT:
                    String v = rs.getString(i + 1);
                    columnValues += v;
                    break;

                case Types.DATE:
                    d = rs.getDate(i + 1); 
                case Types.TIME:
                    if (d == null) d = rs.getTime(i + 1);
                case Types.TIMESTAMP:
                    if (d == null) d = rs.getTimestamp(i + 1);

                    if (d == null) {
                        columnValues += "null";
                    }
                    else {
                        columnValues += "TO_DATE('"
                                  + dateFormat.format(d)
                                  + "', 'YYYY/MM/DD HH24:MI:SS')";
                    }
                    break;

                default:
                    v = rs.getString(i + 1);
                    if (v != null) {
                        columnValues += "'" + v.replaceAll("'", "''") + "'";
                    }
                    else {
                        columnValues += "null";
                    }
                    break;
            }
        }
        p.println(String.format("INSERT INTO %s (%s) values (%s)\n/", 
                                tableName,
                                columnNames,
                                columnValues));
    }
    p.close();
}

补充Metadata Example:

【讨论】:

    【解决方案2】:

    如果List 中已有列名,则可以使用Apache Commons Lang 中的StringUtils.join 构建逗号分隔列表并将其包含在SQL 语句中:

    // the following code assumes: import org.apache.commons.lang.*;
    String tableName="employee";
    List<String> columnsList = new ArrayList<String>();
    columnsList.add("emp_id");  //
    columnsList.add("name");    // sample data
    columnsList.add("salary");  //
    String colString = StringUtils.join(columnsList, ',');
    String paramString = StringUtils.repeat(",?", columnsList.size());
    String sql = String.format(
            "INSERT INTO %s (%s) VALUES (%s)", 
            tableName, colString, paramString.substring(1));
    System.out.println(sql);
    

    导致

    INSERT INTO employee (emp_id,name,salary) VALUES (?,?,?)
    

    编辑:请注意,为了安全起见,您可能应该增强上述代码以将表名和列名括在反引号中,例如

    INSERT INTO `employee` (`emp_id`, ...
    

    【讨论】:

      【解决方案3】:

      如果您以相同的顺序传递与表中列数相同的输入值,那么您甚至不需要提供列名。例如,你可以简单地写成

      插入值(val1、val2、.....)

      如果你不指定列名,那么 mysql 会自动考虑所有列。 但是这种写法是一种非常糟糕的方法,难以维护,并且会引入意想不到的错误。

      【讨论】:

      • 是的,我理解,但这对我的应用程序来说是强制性的。我必须从 UI 授予用户更新几列或插入新记录的权限。所以我可以有任何其他方法来处理这种情况
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-21
      • 2020-12-25
      • 2016-07-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-30
      相关资源
      最近更新 更多