java多线程,将oracle中数据导入到sql到文件(包括大字段转换成字符串)
2013-12-09 19:50
741 查看
import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.Reader; import java.sql.DriverManager; import java.sql.Connection; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.Statement; import oracle.sql.CLOB; public class OracleTest extends Thread{ private int startIndex = 0; private String tableName; private static int fetchCount = 100000; public OracleTest(int startIndex, String tableName) { this.startIndex = startIndex; this.tableName = tableName; } public static void main(String[] args) { try { // 第一步要Jar包:在oracle安装的目录下,盘符:\oracle\ora92\jdbc\lib\ojdbc14.jar // 加载驱动 Class.forName("oracle.jdbc.driver.OracleDriver"); // 连接字符串(协议名:jdbc,子协议名: oracle:thin 子名称:@localhost:1521:oracleDB) // String url ="jdbc:oracle:thin:@localhost:1521:ora"; String tableNameString= "table_name"; int count = getCount(tableNameString); int fetchTimes = count % fetchCount == 0 ? count/fetchCount : (count/fetchCount + 1); for (int i=0; i<fetchTimes; i++) { OracleTest o = new OracleTest(i, tableNameString); o.start(); } } catch (ClassNotFoundException e) { e.printStackTrace(); } } @Override public void run() { int startRow = startIndex * fetchCount; int endRow = (startIndex+1)* fetchCount; System.out.println(Thread.currentThread().getName() +", " + startIndex + "," + startRow + "," + endRow+ ", start"); createInsertSQL(tableName, startRow, endRow); System.out.println(Thread.currentThread().getName() +", " + startIndex + "," + startRow + "," + endRow+ ", END"); } private void createInsertSQL(String tableName, int startRow, int endRow) { String url = "jdbc:oracle:thin:@localhost:1521:oral"; Connection conn = null; Statement st = null; ResultSet rs = null; try { // 建立连接 conn = DriverManager.getConnection(url, "username", "password"); // 创建Statement或者是PreparedStatement语句 st = conn.createStatement(); String sqlStr = "select * from (select t1.*,rownum as rn from " + tableName + " t1 where rownum<=" + endRow +") t2 where t2.rn>" + startRow; // System.out.println(sqlStr); // 执行查询 rs = st.executeQuery(sqlStr); ResultSetMetaData data = rs.getMetaData(); BufferedWriter writer = null; FileWriter fileWriter = null; try { fileWriter = new FileWriter(new File("/Users/cxt/red/tmp/" + tableName + "_" + (startRow/fetchCount) + ".sql")); writer = new BufferedWriter(fileWriter); String sql = "INSERT INTO " + tableName; while (rs.next()) { StringBuffer columnBuffer = new StringBuffer("("); StringBuffer valueBuffer = new StringBuffer("VALUES("); for (int i = 1; i <= data.getColumnCount(); i++) { // 获得指定列的列名 String columnName = data.getColumnName(i); // 获得指定列的数据类型名 String columnTypeName = data.getColumnTypeName(i); // 获得指定列的列值 String columnValue = null; if(columnTypeName.contains("CLOB")) { columnValue = clobToString((oracle.sql.CLOB) rs.getClob(i)); } else { columnValue = rs.getString(i); } if (columnTypeName.contains("DATE")) { if (columnValue.endsWith(".0")) { columnValue = columnValue.substring(0, columnValue.length() - 2); } } if ("null".equals(columnValue)) { columnValue = null; } columnBuffer.append(columnName).append(","); if (!columnTypeName.contains("NUMBER") && null != columnValue) { valueBuffer.append("'").append(columnValue) .append("'"); } else { valueBuffer.append(columnValue); } valueBuffer.append(","); } String column = columnBuffer.toString(); column = column.substring(0, column.length() - 1) + ")"; String value = valueBuffer.toString(); value = value.substring(0, value.length() - 1) + ");"; String sqlString = sql + column + value; // System.out.println(Thread.currentThread().getName()+"; "+sqlString); writer.write(sqlString + "\r\n"); } } catch (Exception e) { e.printStackTrace(); } finally { try { writer.close(); fileWriter.close(); } catch (IOException e) { e.printStackTrace(); } } // while (rs.next()) { // for (int i = 1; i <= data.getColumnCount(); i++) { // // 获得所有列的数目及实际列数 // int columnCount = data.getColumnCount(); // // 获得指定列的列名 // String columnName = data.getColumnName(i); // // 获得指定列的列值 // String columnValue = rs.getString(i); // // 获得指定列的数据类型 // int columnType = data.getColumnType(i); // // 获得指定列的数据类型名 // String columnTypeName = data.getColumnTypeName(i); // // 所在的Catalog名字 // String catalogName = data.getCatalogName(i); // // 对应数据类型的类 // String columnClassName = data.getColumnClassName(i); // // 在数据库中类型的最大字符个数 // int columnDisplaySize = data.getColumnDisplaySize(i); // // 默认的列的标题 // String columnLabel = data.getColumnLabel(i); // // 获得列的模式 // String schemaName = data.getSchemaName(i); // // 某列类型的精确度(类型的长度) // int precision = data.getPrecision(i); // // 小数点后的位数 // int scale = data.getScale(i); // // 获取某列对应的表名 // String tableName = data.getTableName(i); // // 是否自动递增 // boolean isAutoInctement = data.isAutoIncrement(i); // // 在数据库中是否为货币型 // boolean isCurrency = data.isCurrency(i); // // 是否为空 // int isNullable = data.isNullable(i); // // 是否为只读 // boolean isReadOnly = data.isReadOnly(i); // // 能否出现在where中 // boolean isSearchable = data.isSearchable(i); // System.out.println(columnCount); // System.out.println("获得列" + i + "的字段名称:" + columnName); // System.out.println("获得列" + i + "的字段值:" + columnValue); // System.out.println("获得列" + i + "的类型,返回SqlType中的编号:" // + columnType); // System.out.println("获得列" + i + "的数据类型名:" + columnTypeName); // System.out.println("获得列" + i + "所在的Catalog名字:" // + catalogName); // System.out.println("获得列" + i + "对应数据类型的类:" // + columnClassName); // System.out.println("获得列" + i + "在数据库中类型的最大字符个数:" // + columnDisplaySize); // System.out.println("获得列" + i + "的默认的列的标题:" + columnLabel); // System.out.println("获得列" + i + "的模式:" + schemaName); // System.out // .println("获得列" + i + "类型的精确度(类型的长度):" + precision); // System.out.println("获得列" + i + "小数点后的位数:" + scale); // System.out.println("获得列" + i + "对应的表名:" + tableName); // System.out.println("获得列" + i + "是否自动递增:" + isAutoInctement); // System.out.println("获得列" + i + "在数据库中是否为货币型:" + isCurrency); // System.out.println("获得列" + i + "是否为空:" + isNullable); // System.out.println("获得列" + i + "是否为只读:" + isReadOnly); // System.out.println("获得列" + i + "能否出现在where中:" // + isSearchable); // } // } } catch (SQLException e) { e.printStackTrace(); } finally { try { rs.close(); st.close(); conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } private static int getCount(String tableName) { String url = "jdbc:oracle:thin:@10.27.4.121:1521:ora10g"; Connection conn = null; Statement st = null; ResultSet rs = null; try { // 建立连接 conn = DriverManager.getConnection(url, "newpowersite", "newpowersite_xunjie123"); // 创建Statement或者是PreparedStatement语句 st = conn.createStatement(); String sqlStr = "select count(0) from " + tableName; // 执行查询 rs = st.executeQuery(sqlStr); rs.next(); return rs.getInt(1); } catch (Exception ex) { ex.printStackTrace(); } finally { try { rs.close(); st.close(); conn.close(); } catch (SQLException e) { e.printStackTrace(); } } return 0; } // 将字CLOB转成STRING类型 private String clobToString(CLOB clob) throws SQLException, IOException { String reString = ""; if(null == clob) { return null; } Reader is = clob.getCharacterStream();// 得到流 BufferedReader br = new BufferedReader(is); String s = br.readLine(); StringBuffer sb = new StringBuffer(); while (s != null) {// 执行循环将字符串全部取出付值给StringBuffer由StringBuffer转成STRING sb.append(s); s = br.readLine(); } reString = sb.toString(); return reString; } }
上面代码存在的几个问题,以及需要注意的事项:
1、上面代码没有对字符串中的特殊字符进行处理,比如单引号('); 包括对于已经转义的不处理,未转义的要转义
2、上面代码中生成文件的最后是以逗号(,)结尾的,需要替换成分号(;)
3、生成的那件结尾如果包含^M换行符的话,需要处理掉,否则入库会又乱码。
相关文章推荐
- 使用SQL*Loader将CSV文件数据导入ORACLE
- 将sql文件导入PowerDesigner中的方法(将oracle sql文件转换成mysql)
- Oracle pl/sql导入sql文件,插入更新数据,中文乱码问题解决方案
- 解决 在Oracle表数据和xml文件间相互导入导出的PL/SQL 过程
- JPA hibernate spring repository pgsql java 工程(二):sql文件导入数据,测试数据
- 在Oracle表数据和xml文件间相互导入导出的PL/SQL 过程
- Oracle利用SQL将clob字段数据转化为字符串
- 如何在oracle中导入.sql数据结构文件和.dmp数据文件??
- SQL 数据的导入导出,对远程(MSsql,OracleAccess,)数据库的操作以及读取Excel,txt文件中的数据
- 给定一个一oracle建表的sql语句,解析读出的字符串,将表名、字段名、字段类型数据取出,怎么实现啊?
- oracle导入txt数据文件--sql语句
- Oracle导入sql文件数据,中文乱码问题解决方案
- 如何用SQL操作oracle的blob字段里的字符串数据!
- 以Base64字符串形式上传文件——服务器端Java/Servlet接受请求数据中的字符串内容并转换成文件
- MySQL source命令 导入大数据(sql文件,包括phpMyAdmin的备份文件)
- JAVA通过Hibernate将文件写入ORACLE数据的BLOB字段 代码示例
- mysql导入导出数据中文乱码解决方法小结(1、navicat导入问题已解决,创建连接后修改连接属性,选择高级->将使用Mysql字符集复选框去掉,下拉框选择GBK->导入sql文件OK;2、phpmyadmin显示乱码的问题也解决,两步:1.将sql文件以utf8的字符集编码另存,2.将文件中sql语句中的字段字符集编码改成utf8,导入OK)
- Oracle自动导入数据文件(类似bcp的功能)及问题记录SQL*LOADER-704,ORA-12504
- ORACLE判断哪儿儿写数据字符串类型字段不能转换成日期格式
- Oracle sqldevelop的使用(数据即.dmp文件的导入,用户创建,创建连接)