**
大量数据录入遇到sql过长 也就是ora-01704的错误小伙伴可以看过来啦
**
问题类型:
1.针对Oracle数据库的数据录入
2.针对clob类型字段数据录入(其他大类型文本字段同理)
问题分析
-
在使用navicat进行数据传输时失败,报错ora-01704
-
分析ora-01704错误,根据百度,得出问题根源sql语句中引号内字符数不得超过4000
-
网上大部分解决方法,通过存储过程变量形式解决
-
由于本人这里涉及到多数据库,同时单表数据20000+,因此初步方案将利用Java程序+存储过程形式
-
在单条测试的道路上遇到内存溢出的错误(当时单条数据字符数将近5W),不得不采用其他方案
-
这里恰巧遇到这位博主的方案https://www.cnblogs.com/o-andy-o/p/3759829.html
-
我在这位博主的答案进行补充,站在巨人的肩膀上,哈哈哈
以下代码块省略了没必要的字段,主要凸显的事一个clob字段,和一个Number字段,number字段通过Object去录入的。这里对java向数据库传值的一个类型映射,还需要学习,如果哪位老哥有好的整理,在评论区分享下哈
BaseDao baseDao = new BaseDao("com.microsoft.sqlserver.jdbc.SQLServerDriver", "jdbc:sqlserver://192.168.27.11;DatabaseName=HYJXC", "sa", "Aaa123456");
//这里的BaseDao是我这的一个简单调用JDBC类,可忽略,总体就是JDBC执行sql
ResultSet rs = baseDao.executeQuery("select * from HY_JHGL_FHTZD");
String sql="INSERT INTO HY_JHGL_FHTZD (FHTZD_HW_NAME,FHTZD_HW_ID,HY_JCXC_CLXX_ID,FHTZD_CPH,FHTZD_BCFCL,FHTZD_BJCKL) VALUES(?,?,?,?,?)";
Class.forName("oracle.jdbc.OracleDriver");
Connection con = DriverManager.getConnection("jdbc:oracle:thin:@192.168.27.11:1521:ORCL", "JEPLUS_HYJXC", "JEPLUS_HYJXC");
CLOB clob1 = new CLOB((OracleConnection)con);
clob1 = oracle.sql.CLOB.createTemporary((OracleConnection)con,true,1);
CLOB clob2 = new CLOB((OracleConnection)con);
clob2 = oracle.sql.CLOB.createTemporary((OracleConnection)con,true,1);
CLOB clob3 = new CLOB((OracleConnection)con);
clob3 = oracle.sql.CLOB.createTemporary((OracleConnection)con,true,1);
CLOB clob4 = new CLOB((OracleConnection)con);
clob4 = oracle.sql.CLOB.createTemporary((OracleConnection)con,true,1);
while(rs.next()){
OracleConnection OCon = (OracleConnection)con;
OraclePreparedStatement ps = (OraclePreparedStatement)OCon.prepareCall(sql);
clob1.setString(1,rs.getString("FHTZD_HW_NAME"));
clob2.setString(1,rs.getString("FHTZD_HW_ID"));
clob3.setString(1,rs.getString("HY_JCXC_CLXX_ID"));
clob4.setString(1,rs.getString("FHTZD_CPH"));
ps.setClob(1,clob1);
ps.setClob(2,clob2);
ps.setClob(3,clob3);
ps.setClob(4,clob4);
ps.setObject(5,rs.getObject("FHTZD_BCFCL"));
ps.executeUpdate();
ps.close();
ps = null;
}
con.close();
这里我们详细说下这几句代码:
- **CLOB clob1 = new CLOB((OracleConnection)con);**创建了一个clob对象,这里进行类型转换是下面createTemporary需要。
- **clob1 = oracle.sql.CLOB.createTemporary((OracleConnection)con,true,1);**这里的三个参数依次是:第一个是数据库连接,第二个是否将CLOB读入缓冲区高速缓存,第三个是临时CLOB的持续时间。
- **clob1.setString(1,rs.getString(“FHTZD_HW_NAME”));**在临时CLOB的指定位置插入字符。具体我也不是很了解这个1代表啥,希望了解的老哥给讲解讲解
- OracleConnection OCon = (OracleConnection)con;使用新的连接类型以便使用此类型下的OraclePreparedStatement
- OraclePreparedStatement ps = (OraclePreparedStatement)OCon.prepareCall(sql);同preparedStatement的使用
- ps.setClob(1,clob1);同普通preparedStatement的使用
我的数据正在录入中。。。。已经18000+了,速度不快,估计代码还有问题吧,望指正!