创建SQL插入语句到CSV文件

时间:2018-06-29 10:43:00

标签: java sql oracle csv

我希望就棘手的问题获得一些建议。我正在从Oracle数据库中读取数据,并希望从获得的数据中生成插入语句。每个表将具有不同数量的值。

这是当前将columnValue写入csv文件的方法。哪个以1708||1||C||0||A||2018-06-19 00:00:00.0||2118-06-30 00:00:00.0||格式打印。

private void writeToCsvFileWithDatabase() throws SQLException, IOException {

        File file = new File("data.csv");
        selectQueries = new SelectQueries();

        ArrayList<String> queries = SelectQueries.queries();
        ResultSet rs;
        ResultSetMetaData rsmd;

        if (file.exists()){
            Statement stmt = dbConnection.createStatement();
            BufferedWriter writer = new BufferedWriter(new FileWriter("data.csv"));

            for (String query: queries) {
                rs = stmt.executeQuery(query);
                rsmd = rs.getMetaData();
                int columnsNumber = rsmd.getColumnCount();

                while (rs.next()) {
                    for (int i = 1; i <= columnsNumber; i++) {
                        if (i > 1) System.out.print(",  ");
                        String columnValue = rs.getString(i);
                        String tableName = query.substring(query.lastIndexOf(" ")+1);
                        writer.write(columnValue+"||"); //I wish I could just generate the inserts with a library here
                        System.out.print(tableName);
                    }
                    System.out.println("");

                }
            }

        } else {
            throw new FileNotFoundException("data.csv was not found in ReadDatabase.class");
        }

    }

我要么需要代码逻辑来创建插入语句:

INSERT INTO table_name (column1, column2, column3, ...) VALUES (value1, value2, value3, ...);

或找到一个将使用csv file并为我生成插入内容的库。

我知道它们是可以做到这一点的工具,但是我做不到,所以我无法使用它们。

建议?

-------------------问题1 --------------------

我目前有一个问题,以前的值会附加到插入语句中。这是一个示例:

INSERT INTO CAMPAIGN (CAMPAIGN_ID, SHOP_ID, CAMPAIGN_TYPE, SORT_ORDER, STATUS, VALID_FROM, VALID_TILL, CREATED_AT, MODIFIED_AT, CUSTOM_GRID_LAYOUT_CSS, IMAGE_URL, KEY, SHOW_PRODUCTS_FILTER, MOBILE_APP_IMAGE_URL, LAYOUT_ID, SHOW_OWN_BRAND, VALIDATION_STATUS, CAMPAIGN_USAGE_ID, STORE_END_DATE, PAGING_ALLOWED, CAROUSEL_BUTTON_TEXT_COLOR, CAROUSEL_BUTTON_BG_COLOR, CAROUSEL_BUTTON1_LABEL, CAROUSEL_BUTTON1_URL, CAROUSEL_BUTTON2_LABEL, CAROUSEL_BUTTON2_URL, CAROUSEL_HTML_OVERLAY, MOBILE_APP_TEASER_URL, CAROUSEL_CLAIM_URL, CAROUSEL_HERO_URL, CAROUSEL_BOX_COLOR, AVOID_CAMPAIGN_NAV_TEASER, CAROUSEL_BUTTON1_NEW_TAB, CAROUSEL_BUTTON2_NEW_TAB, SALE_QUALIFICATION_ID, SALE_TARGET_CAMPAIGN) 
VALUES (952, 1, 'C', 0, 'A', to_timestamp('2016-11-23 00:00:00.0 AM', 'DD-MON-RR HH.MI.SSXFF AM'), to_timestamp('2116-11-23 00:00:00.0 AM', 'DD-MON-RR HH.MI.SSXFF AM'), to_timestamp('2016-11-23 14:58:53.878264 AM', 'DD-MON-RR HH.MI.SSXFF AM'), to_timestamp('2018-07-01 08:02:57.791698 AM', 'DD-MON-RR HH.MI.SSXFF AM'), null, "campaign/0/0/0/0/9/5/2/4fd7809f-aee4-4d45-a2c7-4a258e09a709.jpg", null, 1, "campaign/0/0/0/0/9/5/2/8504e780-f69f-42c5-93c7-5e163fe4140f.jpg", 5_COL, 0, null, 4, to_timestamp('2116-11-23 00:00:00.0 AM', 'DD-MON-RR HH.MI.SSXFF AM'), 0, null, null, "Artikel ab Do.,10.11.", "https://www.lidl.de", "Unsere Online-Prospekte", "https://www.lidl.de", null, "campaign/0/0/0/0/9/5/2/8943afff-0823-4c35-aad2-2332172bc675.jpg", "campaign/0/0/0/0/9/5/2/96f9c073-fc1c-481d-a2d6-903f8770fecb.png", "campaign/0/0/0/0/9/5/2/81c7c88a-c4fb-4e26-8d92-94716dad642b.jpg", null, 0, 0, 0, null, 0);

这是在第一个循环上很好的Insert语句,但请看一下在第二个循环上会发生什么:

    INSERT INTO CAMPAIGN (CAMPAIGN_ID, SHOP_ID, CAMPAIGN_TYPE, SORT_ORDER, STATUS, VALID_FROM, VALID_TILL, CREATED_AT, MODIFIED_AT, CUSTOM_GRID_LAYOUT_CSS, IMAGE_URL, KEY, SHOW_PRODUCTS_FILTER, MOBILE_APP_IMAGE_URL, LAYOUT_ID, SHOW_OWN_BRAND, VALIDATION_STATUS, CAMPAIGN_USAGE_ID, STORE_END_DATE, PAGING_ALLOWED, CAROUSEL_BUTTON_TEXT_COLOR, CAROUSEL_BUTTON_BG_COLOR, CAROUSEL_BUTTON1_LABEL, CAROUSEL_BUTTON1_URL, CAROUSEL_BUTTON2_LABEL, CAROUSEL_BUTTON2_URL, CAROUSEL_HTML_OVERLAY, MOBILE_APP_TEASER_URL, CAROUSEL_CLAIM_URL, CAROUSEL_HERO_URL, CAROUSEL_BOX_COLOR, AVOID_CAMPAIGN_NAV_TEASER, CAROUSEL_BUTTON1_NEW_TAB, CAROUSEL_BUTTON2_NEW_TAB, SALE_QUALIFICATION_ID, SALE_TARGET_CAMPAIGN) 
VALUES (952, 1, 'C', 0, 'A', to_timestamp('2016-11-23 00:00:00.0 AM', 'DD-MON-RR HH.MI.SSXFF AM'), to_timestamp('2116-11-23 00:00:00.0 AM', 'DD-MON-RR HH.MI.SSXFF AM'), to_timestamp('2016-11-23 14:58:53.878264 AM', 'DD-MON-RR HH.MI.SSXFF AM'), to_timestamp('2018-07-01 08:02:57.791698 AM', 'DD-MON-RR HH.MI.SSXFF AM'), null, "campaign/0/0/0/0/9/5/2/4fd7809f-aee4-4d45-a2c7-4a258e09a709.jpg", null, 1, "campaign/0/0/0/0/9/5/2/8504e780-f69f-42c5-93c7-5e163fe4140f.jpg", 5_COL, 0, null, 4, to_timestamp('2116-11-23 00:00:00.0 AM', 'DD-MON-RR HH.MI.SSXFF AM'), 0, null, null, "Artikel ab Do.,10.11.", "https://www.lidl.de", "Unsere Online-Prospekte", "https://www.lidl.de", null, "campaign/0/0/0/0/9/5/2/8943afff-0823-4c35-aad2-2332172bc675.jpg", "campaign/0/0/0/0/9/5/2/96f9c073-fc1c-481d-a2d6-903f8770fecb.png", "campaign/0/0/0/0/9/5/2/81c7c88a-c4fb-4e26-8d92-94716dad642b.jpg", null, 0, 0, 0, null, 0);
 (953, 1, 'C', 0, 'A', to_timestamp('2016-11-23 00:00:00.0 AM', 'DD-MON-RR HH.MI.SSXFF AM'), to_timestamp('2116-11-23 00:00:00.0 AM', 'DD-MON-RR HH.MI.SSXFF AM'), to_timestamp('2016-11-23 15:09:40.201996 AM', 'DD-MON-RR HH.MI.SSXFF AM'), to_timestamp('2018-07-01 08:02:57.791756 AM', 'DD-MON-RR HH.MI.SSXFF AM'), null, "campaign/0/0/0/0/9/5/3/7c019b7c-5cf7-415c-bbe1-7316083a1339.jpg", null, 1, "campaign/0/0/0/0/9/5/3/c3c97d4c-4018-4e6f-91dd-00417a0e9f08.jpg", 5_COL, 0, null, null, to_timestamp('2116-11-23 00:00:00.0 AM', 'DD-MON-RR HH.MI.SSXFF AM'), 0, null, null, "Ab Do., 24.11.", "https://www.lidl.de", "Unsere Online-Prospekte", "https://www.lidl.de", null, "campaign/0/0/0/0/9/5/3/78e01f6a-435c-4aa4-af17-6231f13abb55.jpg", "campaign/0/0/0/0/9/5/3/a268d712-26fc-4eac-bf58-ebf7d38b2b12.png", "campaign/0/0/0/0/9/5/3/43bacb3e-6b9e-4ada-8b4c-3e7b5d9d9090.jpg", null, 0, 0, 0, null, 0);

第一个insert语句被追加到秒数之后。这将每一次发生,直到每个插入语句中有大量重复项为止。我不确定为什么要一遍又一遍地附加所有先前的语句。

当前代码:

if (file.exists()){
            Statement stmt = dbConnection.createStatement();
            BufferedWriter writer = new BufferedWriter(new FileWriter("data.csv"));

            for (String query: queries) {
                rs = stmt.executeQuery(query);
                rsmd = rs.getMetaData();
                int columnsNumber = rsmd.getColumnCount();
                TABLE_NAME = query.substring(query.lastIndexOf(" ") + 1);
                sb.append(TABLE_NAME).append(" (");
                for (int i = 0; i < columnsNumber; ++i) {
                    String name = rsmd.getColumnName(i + 1);
                    if (i > 0) {
                        sb.append(", ");
                    }

                    sb.append(name);
                }
                sb.append(") VALUES ");

                // generate rows
                while (rs.next()) {

                    sb.append("(");
                    //might not need for loop anymore..
                    for (int i = 0; i < columnsNumber; i++) {
                        if (i > 0) {
                            sb.append(", ");
                        }
                        String columnValue = rs.getString(i + 1);

                        if (columnValue == null) {
                            sb.append("null");
                        } else if (columnValue.contains("-") && Character.isDigit(columnValue.charAt(0))) {
                            columnValue = convertToSqlDate(columnValue);
                            sb.append(columnValue);
                        } else if (Character.isLetter(columnValue.charAt(0)) && columnValue.length() > 2) {
                            //is a varchar
                            sb.append("\"");
                            sb.append(columnValue);
                            sb.append("\"");
                        } else if (Character.isLetter(columnValue.charAt(0))) {
                            //is a Character
                            sb.append("\'");
                            sb.append(columnValue);
                            sb.append("\'");
                        } else {
                            sb.append(columnValue);
                        }
                    }
                    sb.append(");");
                    sb.append("\n");
                    writer.write(sb.toString());

                }
            }
            //writer.write(sb.toString());

        } else {
            throw new FileNotFoundException("data.csv was not found in ReadDatabase.class");
        }

2 个答案:

答案 0 :(得分:2)

以下是一些伪代码,它们根据JDBC结果集生成插入语句:

String TABLE_NAME = "yourTable";
StringBuilder sb = new StringBuilder("INSERT INTO ");
sb.append(TABLE_NAME).append(" (");

rs = stmt.executeQuery(query);
rsmd = rs.getMetaData();
int columnsNumber = rsmd.getColumnCount();
for (int i=0; i < columnsNumber; ++i) {
    String name = rsmd.getColumnName(i+1);
    if (i > 0) {
        sb.append(", ");
    }
    sb.append(name);
}
sb.append(")\nVALUES\n");

// now generate rows
boolean start = true;
while (rs.next()) {
    if (start) {
        start = false;
    }
    else {
        sb.append(",\n");
    }
    sb.append("(");
    for (int i=0; i < columnsNumber; i++) {
        if (i > 0) {
            sb.append(", ");
        }
        String columnValue = rs.getString(i+1);
        sb.append(columnValue);
    }
    sb.append(")");
}

sb.append(";");

答案 1 :(得分:0)

您可以使用Apache Commons中的DBUtils为您完成一些工作。它具有RowProcessor类,该类使您可以将ResultSet作为映射获取,因此可以更轻松地对其进行处理。进一步的步骤将是向该类添加自定义方法并为您的语句定义模板。

考虑示例。

class CustomRowProcessor extends BasicRowProcessor {
  List<String> getInsertList(ResultSet rs) throws SQLException {
    List<String> res = new ArrayList<>();
    while (rs.next()) {
      String tableName = rs.getMetaData().getTableName(1);
      String template = "INSERT INTO %s (%s) VALUES (%s);";
      String columns = toMap(rs).keySet().stream()
          .collect(Collectors.joining(", "));
      String values = toMap(rs).values().stream()
          .map(v -> "'" + v + "'")
          .collect(Collectors.joining(", "));
      res.add(String.format(template, tableName, columns, values));
    }
    return res;
  }
}

在类路径上具有上述内容和DBUtils,可以按如下方式重构原始代码的很大一部分。

for (String query : queries) {
  rs = stmt.executeQuery(query);
  for (String insert : new CustomRowProcessor().getInsertList(rs)) {
    writer.write(insert + "\n");
  }
}