我希望就棘手的问题获得一些建议。我正在从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");
}
答案 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");
}
}