Java中使用Oracle的客户端 load data和sqlldr命令执行数据导入到数据库中
Windows环境下测试代码:
import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.PrintWriter; import java.util.Scanner; public class testTimer { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub // ./szrpp_files/clPath //写控制文件.ctl String fileRoute = "D:\\test\\";//文件地址路径 String fileName = "test2015.txt";//数据文件名 String tableName = "test_table";//表名 String fieldName = "(name,userpwd,sex)";//要写入表的字段 String ctlfileName = "test_table.ctl";//控制文件名 stlFileWriter(fileRoute,fileName,tableName,fieldName,ctlfileName); //要执行的DOS命令 String user = "SCOTT"; String psw = "123"; String Database = "//127.0.1.1:1521/ORCL"; IP要指向数据库服务器的地址 String logfileName = "test_table.log"; Executive(user,psw,Database,fileRoute,ctlfileName,logfileName); } /** * * 写控制文件.ctl * @param fileRoute 数据文件地址路径 * @param fileName 数据文件名 * @param tableName 表名 * @param fieldName 要写入表的字段 * @param ctlfileName 控制文件名 */ public static void stlFileWriter(String fileRoute,String fileName,String tableName,String fieldName,String ctlfileName) { FileWriter fw = null; String strctl = "OPTIONS (skip=0)" + " LOAD DATA INFILE '"+fileRoute+""+fileName+"'" + " APPEND INTO TABLE "+tableName+"" + " FIELDS TERMINATED BY ','" + " OPTIONALLY ENCLOSED BY \"'\"" + " TRAILING NULLCOLS "+fieldName+""; try { fw = new FileWriter(fileRoute+""+ctlfileName); fw.write(strctl); } catch (IOException e) { e.printStackTrace(); } finally { try { fw.flush(); fw.close(); } catch (IOException e) { e.printStackTrace(); } } } /** * 调用系统DOS命令 * @param user * @param psw * @param Database * @param fileRoute 文件路径 * @param ctlfileName 控制文件名 * @param logfileName 日志文件名 */ public static void Executive(String user,String psw,String Database,String fileRoute,String ctlfileName,String logfileName) { InputStream ins = null; //要执行的DOS命令 --数据库 用户名 密码 user/password@database String dos="sqlldr "+user+"/"+psw+"@"+Database+" control="+fileRoute+""+ctlfileName+" log="+fileRoute+""+logfileName; String[] cmd = new String[] { "cmd.exe", "/C", dos }; // 命令 try { Process process = Runtime.getRuntime().exec(cmd); ins = process.getInputStream(); // 获取执行cmd命令后的信息 BufferedReader reader = new BufferedReader(new InputStreamReader(ins)); String line = null; while ((line = reader.readLine()) != null) { String msg = new String(line.getBytes("ISO-8859-1"), "UTF-8"); System.out.println(msg); // 输出 } int exitValue = process.waitFor(); if(exitValue==0) { System.out.println("返回值:" + exitValue+"\n数据导入成功"); }else { System.out.println("返回值:" + exitValue+"\n数据导入失败"); } process.getOutputStream().close(); // 关闭 } catch (Exception e) { e.printStackTrace(); } } }
Linux环境下的测试代码:
import java.io.BufferedReader; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; public class TestLinux { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub // ./szrpp_files/clPath //写控制文件.ctl String fileRoute = "/home/test/";//文件地址路径 String fileName = "test2015.txt";//数据文件名 String tableName = "test_table";//表名 String fieldName = "(name,userpwd,sex)";//要写入表的字段 String ctlfileName = "ctltest.ctl";//控制文件名 stlFileWriter(fileRoute,fileName,tableName,fieldName,ctlfileName); //要执行的DOS命令 String user = "scott"; String psw = "123"; String Database = "//127.0.0.1:1521/ORCL"; String logfileName = "logtext.log"; Executive(user,psw,Database,fileRoute,ctlfileName,logfileName); } /** * * 写控制文件.ctl * @param fileRoute 数据文件地址路径 * @param fileName 数据文件名 * @param tableName 表名 * @param fieldName 要写入表的字段 * @param ctlfileName 控制文件名 */ public static void stlFileWriter(String fileRoute,String fileName,String tableName,String fieldName,String ctlfileName) { FileWriter fw = null; String strctl = "OPTIONS (skip=0)" + " LOAD DATA INFILE '"+fileRoute+""+fileName+"'" + " APPEND INTO TABLE "+tableName+"" + " FIELDS TERMINATED BY ','" + " OPTIONALLY ENCLOSED BY \"'\"" + " TRAILING NULLCOLS "+fieldName+""; try { fw = new FileWriter(fileRoute+""+ctlfileName); fw.write(strctl); } catch (IOException e) { e.printStackTrace(); } finally { try { fw.flush(); fw.close(); } catch (IOException e) { e.printStackTrace(); } } } /** * 调用系统DOS命令 * @param user * @param psw * @param Database * @param fileRoute 文件路径 * @param ctlfileName 控制文件名 * @param logfileName 日志文件名 */ public static void Executive(String user,String psw,String Database,String fileRoute,String ctlfileName,String logfileName) { InputStream ins = null; //要执行的DOS命令 String dos="sqlldr "+user+"/"+psw+"@"+Database+" control="+fileRoute+""+ctlfileName+" log="+fileRoute+""+logfileName; //Linux环境下注释掉不需要CMD 直接执行DOS就可以 //String[] cmd = new String[] //{ "cmd.exe", "/C", dos }; // Windows环境 命令 try { Process process = Runtime.getRuntime().exec(dos); ins = process.getInputStream(); // 获取执行cmd命令后的信息 BufferedReader reader = new BufferedReader(new InputStreamReader(ins)); String line = null; while ((line = reader.readLine()) != null) { String msg = new String(line.getBytes("ISO-8859-1"), "UTF-8"); System.out.println(msg); // 输出 } int exitValue = process.waitFor(); if(exitValue==0) { System.out.println("返回值:" + exitValue+"\n数据导入成功"); }else { System.out.println("返回值:" + exitValue+"\n数据导入失败"); } process.getOutputStream().close(); // 关闭 } catch (Exception e) { e.printStackTrace(); } } }
特别注意:
注意cmd命令执行的密码字符不能过于复杂 不能带有特殊符号 以免执行不通过 譬如有!@#¥%……&*之类的
所以在Oracle数据库设置密码是不要太复杂 同时在数据库集群环境下的任何一IP地址都可以访问数据库的
1.你的程序部署在什么服务器下面 是在Oracle数据库服务器下 数据库连接IP地址配置可以不指明,如果部署在其他服务器下不在数据库服务器下数据库名的连接地址要指向明确的 所在数据库服务器IP地址,这个自己可以多次试验测试就晓得了。
程序部署所在的服务器一定要安装oracle客户端才能执行导入数据命令
2.测试程序只是实现了功能,但是放到你的项目程序中一定要多多测试自然会发现问题的,这个测试代码放到你的项目中时候一定要注意一些代码的改造,具体自己多测试就发现了。可以简单说明下 就在Executive()这个方法里面的代码只要稍加改造就好了,自己摸索下就明白了。
3.控制文件路径最好这样使用在引用到项目中时候:control="+clPath+File.separator+ctlfileName+" log="+clPath+File.separator+logfileName
4.针对这段代码具体描述下
String strctl = "OPTIONS (skip=0)" + // 0是从第一行开始 1是 从第二行 " LOAD DATA INFILE '"+fileRoute+""+fileName+"'" + " APPEND INTO TABLE "+tableName+"" + //覆盖写入 " FIELDS TERMINATED BY ',' " + //--数据中每行记录用","分隔 ,TERMINATED用于控制字段的分隔符,可以为多个字符。 " OPTIONALLY ENCLOSED BY \"'\"" + //源文件有引号 '',这里去掉 ''''" " TRAILING NULLCOLS "+fieldName+"";//--表的字段没有对应的值时允许为空 源数据没有对应,写入null