方案步骤为:数据导出到文件(增量或全量),通知接口文件就绪(上传到ftp或提供下载url),接收方下载文件,解析文件并入库。Oracle需要建立对应的临时表和正式表,入库步骤为:清空临时表,批量插入数据,再合并到正式表。
一、数据:
数据可以推送,也可以拉取,可以考虑以数据最新日期为临界点
数据可以导出到文件,也可以接口请求正文直接传输,字段分隔符可选|@|
二、SQL:
清空临时表
delete from temp_table;
临时表批量插入:values后面动态生成,批量插入时有多行into,数据量过大时建议按1000条数据分多条sql插入
insert all
into temp_table values (‘id_1’,’value_1’)
into temp_table values (‘id_2’,’value_2’)
select 1 rom dual;
合并数据到正式表:update set不能更新主键id,values后面动态生成
merge into formal_table n
using (select * from temp_table t on t.id=n.id)
when matched then update set n.name=t.name,n.age=t.age
when not matched then insert into formal_table values (t.id,t.name,t.age);
三:Java:JdbcTemplate,执行sql语句时不能有末尾的分号
JdbcTemplate jdbc = new JdbcTemplate(dataSource); //使用已配置好的数据源
SqlRowSet rowSet = jdbc.queryForRowSet(“select * from temp_table where rownum=1“); //临时表和正式表结构完全一样
String[] columnNames = rowSet.getMetaData().getColumnNames(); //获取表的所有列
jdbc.update(sql); //执行insert或merge语句
String[] values=StringUtils.splitByWholeSeparatorPreserveAllTokens(line,”|@|”); //切分数据行
StringBuilder sqlInsert = new StringBuilder(“insert all ”); //拼接sql insert语句
sqlInsert.append(“into temp_table values (‘“).append(StringUtilis.join(split,”’,’”,0,Math.min(split.length, columnNames.length))).append(“’) ”);
sqlInsert.append(“select 1 from dual”);
StringBuilder sqlMerge = new StringBuilder(“merge into formal_table n ”); //拼接sql merge语句
sqlMerge.append(“using (select * from temp_table) t on t.id=n.id ”);
sqlMerge.append(“when matched then update set ”);
for(int i=1;i<columnNames.length;i++) sqlMerge.append(“n.”+columnNames[i]+”=t.”+columnNames[i]+”,”); //不更新主键i=0
sqlMerge.setCharAt(sqlMerge.length()-1, ‘ ’); //替换末尾逗号为换行符
sqlMerge.append(“when not matched then insert values (t.”).append(StringUtils.join(columnNames, “,t.”)).append(“)”);
四:设计