PreparedStatement的addBatch方法抛出异常

绝望的奶黄包 2016-12-20 11:28:24
插入的是List对象pointDataList,每个pointDataList.对象里面还包含一个List<TestDataPointConclusionBean>.

String insertDataSql = "insert into tdpointdata(id,subjectid,tempcode,chromosomecode,chromosomeposition,ref,alts,alt,pfirst,afnormal,callnormal,afdisease,calldisease) values (?,?,?,?,?,?,?,?,?,?,?,?,?)";
PreparedStatement pst = null;
//省略jdbc连接,try catch ,关闭自动提交等无关代码
pst = conn.prepareStatement(insertDataSql);
for (int i = 0; i < pointDataList.size(); i++) {
pst.setLong(1, dataId);
pst.setLong(2, pointDataList.get(i).getSubjectId());
pst.setString(3, pointDataList.get(i).getTempCode());
pst.setString(4, pointDataList.get(i).getChromosomeCode());
pst.setLong(5, pointDataList.get(i).getChromosomePosition());
pst.setString(6, pointDataList.get(i).getRef());
pst.setString(7, pointDataList.get(i).getAlts());
pst.setString(8, pointDataList.get(i).getAlt());
pst.setDouble(9, pointDataList.get(i).getPfirst());
pst.setFloat(10, pointDataList.get(i).getAfnormal());
pst.setInt(11, pointDataList.get(i).getCallnormal());
pst.setFloat(12, pointDataList.get(i).getAfdisease());
pst.setInt(13, pointDataList.get(i).getCalldisease());
//第一次可以执行addBatch
pst.addBatch();
List<TestDataPointConclusionBean> pointConclusionList = pointDataList.get(i).getPointDataConclusions();
if (CollectionUtils.isEmpty(pointConclusionList)) {
dataId++;
continue;
}
for (int j = 0; j < pointConclusionList.size(); j++) {
//这里抛出异常
pst.addBatch(insertConSql + "(" + conclusionId + maintenanceSql + dataId + "," + pointConclusionList.get(j).toString() + ")");
conclusionId++;
}
dataId++;
pst.executeBatch();
conn.commit();
}

对象名有点长。懒得看的话就当做是学生-成绩表,学生表的主键是成绩表的外键。
现在插入一个学生后,再开始批量插入成绩数据。就会进入异常。
在此处进入异常


org.postgresql.util.PSQLException: 在 PreparedStatement 上不能使用获取查询字符的查询方法。
...全文
616 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
huahua.Dr 2018-09-18
  • 打赏
  • 举报
回复
“对个sql语句”改成 “多个sql语句”,谢谢
huahua.Dr 2018-09-18
  • 打赏
  • 举报
回复
兄弟,报异常的地方原因是不能使用prepareStatement接口去实现addBatch()对个sql语句,addBatch()方法不接受参数的输入(即使传入的参数也无法执行,没有重写这个方法因此不支持),你可以查看一下官方文档API,大概意思是说:addBatch()只是使用适当的setXXX()方法将设置的绑定参数添加到批处理中,(对于CallbleStatement或OracleCallableStatement对象也是一样)

For prepared statements, update batching is used to batch multiple executions of the same statement with different sets of bind parameters. For a PreparedStatement or OraclePreparedStatement object, the addBatch() method takes no input--it simply adds the operation to the batch using the bind parameters last set by the appropriate setXXX() methods. (This is also true for CallableStatement or OracleCallableStatement objects, but remember that in the Oracle implementation of standard update batching, you will probably see no performance improvement in batching callable statements.)

For example (again assuming a Connection instance conn):

...
PreparedStatement pstmt =
conn.prepareStatement("INSERT INTO employees VALUES(?, ?)");

pstmt.setInt(1, 2000);
pstmt.setString(2, "Milo Mumford");
pstmt.addBatch();

pstmt.setInt(1, 3000);
pstmt.setString(2, "Sulu Simpson");
pstmt.addBatch();
...

At this point, two operations are in the batch.

Because a batch is associated with a single prepared statement object, you can batch only repeated executions of a single prepared statement, as in this example.

可以使用createStatement来实现这个功能,但性能就不好说了。。。。
...
Statement stmt = conn.createStatement();

stmt.addBatch("INSERT INTO emp VALUES(1000, 'Joe Jones')");
stmt.addBatch("INSERT INTO dept VALUES(260, 'Sales')");
stmt.addBatch("INSERT INTO emp_dept VALUES(1000, 260)");
...

绝望的奶黄包 2016-12-20
  • 打赏
  • 举报
回复
附上第二次插入的拼接sql,其实在异常里面也能看到sql,此处再贴出来

insert into tdpointdataconclusion (id,createdate,creator,datastatus,lastmodifier,lastmodifydate,testdatapointid,extrasamplecode,type,conclusion) values (883640,Tue Dec 20 00:00:00 CST 2016,2,1,0,null,3605,'GT_47',1,1)
颐牟权月 2016-12-20
  • 打赏
  • 举报
回复

        PreparedStatement pst1 = null;
        PreparedStatement pst2 = null;
        try {
            pst1 = conn.prepareStatement(insertDataSql);
            pst2 = conn.prepareStatement(insertConSql);
            for (int i = 0; i < pointDataList.size(); i++) {
                pst1.setLong(1, dataId);
                //.......
                pst1.addBatch();
                List<TestDataPointConclusionBean> pointConclusionList = pointDataList.get(i).getPointDataConclusions();
                if (CollectionUtils.isEmpty(pointConclusionList)) {
                    dataId++;
                    continue;
                }
                for (int j = 0; j < pointConclusionList.size(); j++) {
                    if (!pointConclusionList.get(j).isValid()) {
                        continue;
                    }
                    pst2.setLong(1, conclusionId);
                    //......
                    conclusionId++;
                }
                dataId++;
                //每2000条数据提交一次
                if ((i > 0 && i % 10 == 0) || i == pointDataList.size() - 1) {
                    pst2.executeBatch();
                    conn.commit();
                }
            }
            pst1.executeBatch();
            conn.commit();
        } catch (Exception e) {
            throw new RayseException(TmmsErrCode.TMMS_DATA_GENE_IMPORT_FAIL);
        } finally {
            try {
                if (pst1 != null) {
                    pst1.close();
                }
                if (pst2 != null) {
                    pst2.close();
                }
                if (conn != null) {
                    conn.close();
                }
            } catch (SQLException e) {
                
            }
        }
绝望的奶黄包 2016-12-20
  • 打赏
  • 举报
回复
刚才仔细查看了一下API,发现PreparedStatement 只重写了addBatch的无参方法,也就是只能使用一句sql,通过设置不同的参数来达到批量编译。那么混合的插入sql有什么好的方式么。 正确的操作应该是所有的学生批量插入,再将所有成绩批量插入。 但是成绩中关联了学生的id 所以只能插入一个学生,然后再插入学生的成绩。 再插入一个学生,再插入学生的成绩 这种混合方式应该如何处理
《java面试800题(包括java,数据库,前台等,绝对全面)》 Q0027 哪些SQL语句在执行时是自动提交的? 数据定义语言DDL是自动提交的。 Q0028 索引对数据库的影响? 提高查询速度 Q0029 主外键有什么关系? 外键是从某个表的一个字段指向另外一个表的主健字段,两个字段的类型和精度应该一致,外键的值必须在主键中存在 Q0030 在数据库中什么代表一条记录? 主健 Q0031 如何编写效率高的SQL语句? "1.根据查询条件建立合适的index 2.因为SQL是从右向左解析,多表查询时,记录数少的表放在右边 3.多个条件时,收敛快的条件放在右边。 4.避免使用复杂的集合函数,象not in等。 5.避免在条件中对字段进行函数操作 6.尽量避免使用select *,应该写出需要查询的字段 7.在java中尽量使用preparestatement执行sql,从而共享执行计划" Q0032 Oracle的集合操作函数,如sum(),avg(),max(),min(),与select,where,grouby,having的先后顺序,使用方法 Oracle集合查询基本知识,只有进行分组的列,才可以取在集合查询SQL语句中取字段,先Group By,再Having作为集合查询的条件 Q0033 在Oracle数据库中,给定一个表,其中一列有索引,现在用这个列作为查询条件,因为用到了索引,速度一定会快吗? 答案是否定的,比如在这个列中使用‘%sdfd%’来进行模糊查询 Q0034 给定了一些创建数据库试图的SQL语句问什么条件下才可以对试图执行修改,增加,删除操作 特别强调了WITH CHECK OPTION这个约束的含义,使用,产生的不同结果。参考Oracle 视图的基本知识,单个表上的视图,多个表的联合试图,更新视图与表之间的关系.http://www.gzu521.com/it/oracle/zonghe/200904/20748_2.htm Q0035 是不是表或者其他对象不存在,就一定不能在Oracle中创建视图? 否,可通过FORCE选项执行强制生成视图,好处是在表不存在的时候,先创建视图 Q0036 如何创建oracle函数索引 "SQL>create index non_fbi on sale_contacts (surname); SQL>analyze index non_fbi compute statistics; SQL>:analyze table sale_contacts compute statistics; SQL>SELECT count(*) FROM sale_contacts WHERE UPPER(surname) = 'ELLISON'; Execution Plan ---------------------------------------------------------- 0 SELECT STATEMENT Optimizer=CHOOSE (Cost=3 Card=1 Bytes=17) 1 0 SORT (AGGREGATE) 2 1 TABLE ACCESS (FULL) OF 'SALES_CONTACTS' (Cost=3 Card=16 Bytes=272) " Q0037 "ORACLE锁的管理 " "ORACLE里锁有以下几种模式: 0:none 1:null 空 2:Row-S 行共享(RS):共享表锁 3:Row-X 行专用(RX):用于行的修改 4:Share 共享锁(S):阻止其他DML操作 5:S/Row-X 共享行专用(SRX):阻止其他事务操作 6:exclusive 专用(X):独立访问使用 数字越大锁级别越高, 影响的操作越多。" Q0038 创建XML文件的格式? " …" Q0039 java接口与抽象类的区别 "1.接口可以多重继承 ,抽象类不可以 2.接口定义方法,不给实现;而抽象类可以实现部分方法 3.接口中基本数据类型的数据成员,都默认为static和final,抽象类则不是 如果事先知道某种东西会成为基础类, 那么第一个选择就是把它变成一个接口。 只有在必须使用方法定义或者成员变量的时候,才应考虑采用抽象类。" Q0040 Java关键字 "51个:abstract, boolean, break, byte, case, catch, char, class, const, continue, default, do, double, else, extends, final, finally, float, for, goto, if, implements, import, instanceof, int, interface, long, native, new, package, private, protected, public, return, short, static, strictfp, super, switch, synchronized, this, throw, throws, transient, try, void, volatile, while. " Q0041 Java保留字 11个:byValue, cast, false, future, generic, inner, operator, outer, rest, true, var. Q0042 Java的值传递的规则? Java基本类型的都是值传递,对象使用的都是引用传递 Q0043 java相关概念 "static:静态,无需实例化,可直接引用,全局只有一份copy,修饰变量和方法 final:最终的,不可继承、不可修改,修饰变量、方法、类 volatile:volatile变量表示保证它必须是与主内存保持一致,它实际是""变量的同步"", 也就是说对于volatile变量的操作是原子型的,如用在long 或 double变量前,一般用于多线程编程。 abstract:抽象,必须重载,修饰类和方法 native:把java代码和其他语言的代码集成起来 synchronized:控制多个并发线程对共享数据的访问 throwsException:异常处理" Q0044 this&super的异同 "this :引用当前对象 super:引用当前对象的父类 使用情况: (1) super.variable //用来访问父类被隐藏的成员变量 (2) super.Method([paramlist]) //用来调用父类中被重载的方法 (3) super.([paramlist]) //调用父类中的构造函数 在类方法中(static),不能使用this或super修饰符 " Q0045 Java中是怎样捕获异常的? "try { //statement01 } catch(Exception e) { //statement02 } finally { //statement03 }" Q0046 一个文件中是否可以有多个public类? 不可以 Q0047 子类是否可以访问父类的私有成员? 不可以 Q0048 NULL是否是Java的关键字? 不是。null,false,true是保留字 Q0049 一个有序数组和一个无序数组,从无序数组中取出每条记录与有序数组比较,如果符合条件,把无序数组中的值加入到有序数组中,问这是什么排序? 插入排序法 Q0050 程序与进程的区别? 程序是为了完成某种任务而设计的软件,比如OpenOffice是程序。什么是进程呢?进程就是 运行中的程序。 一个运行着的程序,可能有多个进程。 Q0051 设计模式主要几种 "创建模式 factory工厂模式、prototype原始模型模式、singleton单例模式、builder建造模式 结构模式 facade门面模式、proxy代理模式、adapter适配器(变压器)模式、composite合成模式、decorator装饰模式、bridge桥梁模式、flyweight享元模式 行为模式 template模板方法模式、memento备忘录模式、observer观察者模式、command命令模式、state状态模式、strategy策略模式、mediator调停者模式、interpreter解释器模式、visitor访问者模式、chain of responsibility责任链模式" Q0052 构造函数的相关知识? "构造函数(constructor )在对象创建时初始化。 构造函数是和类同名的函数,没有返回类型,构造函数不能在普通的程序里面调用,只有当这个类被应用new实例化的时候才会被运行。构造函数没有返回类型,实际上,构造函数返回的就是这个class本身。 类初始化时构造函数调用顺序: (1)初始化对象的存储空间为零或null值; (2)调用父类构造函数; (3)按顺序分别调用类成员变量和实例成员变量的初始化表达式; (4)调用本身构造函数。" Q0053 "Public class Servlet extends HttpServlet{ int i; doget(){ i++; out.print(i); } } 每次访问时i是否变化?" 会 Q0054 类的加载过程? "类的初始化过程 当创建一个对象时,对象的各个变量根据其类型被设置为相应的默认初始值,然后调用构造方法,而每次调用构造方法都是要执行三个阶段: 1.调用超类的构造方法; 2.由初始化语句对给变量进行初始化; 3.执行构造方法的体。" Q0055 系统运行时的最小单位是什么? 线程 Q0056 Java的编码规范? Q0057 Java的命名规范? Q0058 一个Java抽象类声明了一个方法并会抛出一个异常,问继承这个抽象类的子类,实现了这个方法,这个方法声明是不是一定要抛出一模一样的异常,可不可以不抛,或者抛出的异常比抽象类的异常范围大,或者小? 可以不抛,或者比抽象类的小,但绝对不能抛出的异常比抽象类的大 Q0059 找出weblogic-ejb-jar.xml文件中的错误。 "正确的文档 Catalog WebLogic_CMP_RDBMS 7.0 META-INF/weblogic-cmp-rdbms-jar.xml com.ejb.CatalogHome " Q0060 JDBC批量更新的作用和用法 "提高执行效率。减少执行时间。 Statement sm = cn.createStatement(); sm.addBatch(sql1); sm.addBatch(sql2); ... sm.executeBatch() 或者 PreparedStatement ps = cn.preparedStatement(sql); { ps.setXXX(1,xxx); ... ps.addBatch(); } ps.executeBatch();" Q0061 事务的特性是什么? "事务有四种特性:ACID Atomicity(原子性) 事务中的操作或者全部完成,或者全部不完成。 Consistency(一致性) 事务执行的结果是从一个一致性状态转移到另一个一致性状态。 Isolation(隔离性) 一个事务的执行不能被其它事务干扰,即并发事务间内部数据是隔离的。 Durability(持久性) 事务开始执行后,它对系统中数据的改变应该是恒定的,不应受其它操作或故障的影响。 " Q0062 事务有几种属性?分别是什么? "事务的属性有6种 1.Required:当处于事务范围内的客户端应用调用组件商务方法时,组件商务方法执行在原有的客户端事务范围内; 2.RequiredNew:当处于事务范围内的客户端应用调用组件商务方法时,EJB容器启动一个新的事务过程,组件商务方法执行在新事务过程范围内; 3.Mandatory:如果调用EJB组件商务方法的客户端应用不处于事务范围内,则EJB容器抛出TransactionRequiredException异常,强制客户端启动事务过程; 4.NotSupported:EJB组件的商务方法不需要运行在事务过程中。如果调用EJB组件方法的客户端应用处于事务过程中,则调用组件商务方法时原有事务过程挂起,直至组件方法运行结束; 5.Supports:组件方法必须处于事务范围内。如果调用组件商务方法的客户端不处于事务过程中,则EJB容器启动新的事务过程;6.Never:组件方法不需要运行在事务过程中。如果调用组件商务方法的客户端应用处于事务范围内,则EJB容器抛出RemoteException异常。 "

67,513

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧