標籤:
mybatis 批量插入資料到oracle報 ”java.sql.SQLException: ORA-00933: SQL 命令未正確結束“ 錯誤解決方案
oracle批量插入使用 insert all into table(...) values(...) into table(...) values(...) select * from dual; 語句來解決,但一直報如下錯誤
### The error may involve ApplaudDaoImpl.addList-Inline### The error occurred while setting parameters### SQL: INSERT ALL INTO T_APPLAUD ( ID, USER_ID, BUSINESS_TYPE, PRODUCT_ID, CREATE_TIME ) VALUES ( ?, ?, ?, ?, ? ) INTO T_APPLAUD ( ID, USER_ID, BUSINESS_TYPE, PRODUCT_ID, CREATE_TIME ) VALUES ( ?, ?, ?, ?, ? ) INTO T_APPLAUD ( ID, USER_ID, BUSINESS_TYPE, PRODUCT_ID, CREATE_TIME ) VALUES ( ?, ?, ?, ?, ? ) INTO T_APPLAUD ( ID, USER_ID, BUSINESS_TYPE, PRODUCT_ID, CREATE_TIME ) VALUES ( ?, ?, ?, ?, ? ) INTO T_APPLAUD ( ID, USER_ID, BUSINESS_TYPE, PRODUCT_ID, CREATE_TIME ) VALUES ( ?, ?, ?, ?, ? ) INTO T_APPLAUD ( ID, USER_ID, BUSINESS_TYPE, PRODUCT_ID, CREATE_TIME ) VALUES ( ?, ?, ?, ?, ? ) INTO T_APPLAUD ( ID, USER_ID, BUSINESS_TYPE, PRODUCT_ID, CREATE_TIME ) VALUES ( ?, ?, ?, ?, ? ) INTO T_APPLAUD ( ID, USER_ID, BUSINESS_TYPE, PRODUCT_ID, CREATE_TIME ) VALUES ( ?, ?, ?, ?, ? ) INTO T_APPLAUD ( ID, USER_ID, BUSINESS_TYPE, PRODUCT_ID, CREATE_TIME ) VALUES ( ?, ?, ?, ?, ? ) INTO T_APPLAUD ( ID, USER_ID, BUSINESS_TYPE, PRODUCT_ID, CREATE_TIME ) VALUES ( ?, ?, ?, ?, ? ) INTO T_APPLAUD ( ID, USER_ID, BUSINESS_TYPE, PRODUCT_ID, CREATE_TIME ) VALUES ( ?, ?, ?, ?, ? ) INTO T_APPLAUD ( ID, USER_ID, BUSINESS_TYPE, PRODUCT_ID, CREATE_TIME ) VALUES ( ?, ?, ?, ?, ? ) INTO T_APPLAUD ( ID, USER_ID, BUSINESS_TYPE, PRODUCT_ID, CREATE_TIME ) VALUES ( ?, ?, ?, ?, ? ) INTO T_APPLAUD ( ID, USER_ID, BUSINESS_TYPE, PRODUCT_ID, CREATE_TIME ) VALUES ( ?, ?, ?, ?, ? ) INTO T_APPLAUD ( ID, USER_ID, BUSINESS_TYPE, PRODUCT_ID, CREATE_TIME ) VALUES ( ?, ?, ?, ?, ? ) SELECT 1 FROM DUAL### Cause: java.sql.SQLException: ORA-00933: SQL 命令未正確結束; bad SQL grammar []; nested exception is java.sql.SQLException: ORA-00933: SQL 命令未正確結束 at org.springframework.jdbc.support.SQLStateSQLExceptionTranslator.doTranslate(SQLStateSQLExceptionTranslator.java:97) at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72) at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80) at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80) at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:73) at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:368) at com.sun.proxy.$Proxy12.insert(Unknown Source) at org.mybatis.spring.SqlSessionTemplate.insert(SqlSessionTemplate.java:240) at com.teshehui.applaud.dao.impl.ApplaudDaoImpl.addList(ApplaudDaoImpl.java:33) ... 52 moreCaused by: java.sql.SQLException: ORA-00933: SQL 命令未正確結束 at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112) at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:331) at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:288) at oracle.jdbc.driver.T4C8Oall.receive(T4C8Oall.java:745) at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:216) at oracle.jdbc.driver.T4CPreparedStatement.executeForRows(T4CPreparedStatement.java:966) at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1170) at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3339) at oracle.jdbc.driver.OraclePreparedStatement.execute(OraclePreparedStatement.java:3445) at com.jolbox.bonecp.PreparedStatementHandle.execute(PreparedStatementHandle.java:138) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) at org.apache.ibatis.logging.jdbc.PreparedStatementLogger.invoke(PreparedStatementLogger.java:55) at com.sun.proxy.$Proxy17.execute(Unknown Source) at org.apache.ibatis.executor.statement.PreparedStatementHandler.update(PreparedStatementHandler.java:41) at org.apache.ibatis.executor.statement.RoutingStatementHandler.update(RoutingStatementHandler.java:66) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) at com.sun.proxy.$Proxy15.update(Unknown Source) at org.apache.ibatis.executor.SimpleExecutor.doUpdate(SimpleExecutor.java:45) at org.apache.ibatis.executor.BaseExecutor.update(BaseExecutor.java:100) at org.apache.ibatis.executor.CachingExecutor.update(CachingExecutor.java:75) at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:148) at org.apache.ibatis.session.defaults.DefaultSqlSession.insert(DefaultSqlSession.java:137) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:358) ... 55 more
Google無數次,自己跟蹤調試也沒結果,最後在stackoverflow mybatis問答區偶然看到了網友分析(連結見末尾),測試發現解決了,原因竟是mybatis批量插入oracle時需要顯式指定為 useGeneratedKeys="false" 不然報錯~~~
正確的mybatis的mapper的sql配置如下:
1 <insert id="addList" parameterType="java.util.List" useGeneratedKeys="false"> 2 INSERT ALL 3 <foreach item="item" index="index" collection="list"> 4 INTO T_APPLAUD 5 ( 6 ID, 7 USER_ID, 8 BUSINESS_TYPE, 9 PRODUCT_ID,10 CREATE_TIME11 ) VALUES12 (13 #{item.id, jdbcType=NUMERIC},14 #{item.userId, jdbcType=VARCHAR},15 #{item.businessType, jdbcType=VARCHAR},16 #{item.productId, jdbcType=VARCHAR},17 #{item.createdTime, jdbcType=NUMERIC} 18 )19 </foreach>20 SELECT 1 FROM DUAL21 </insert>
另外一種方法是 insert into table(...) (select ... from dual) union all (select ... from dual)
1 <insert id="addList" parameterType="java.util.List" useGeneratedKeys="false"> 2 INSERT INTO T_APPLAUD 3 ( 4 ID, 5 USER_ID, 6 BUSINESS_TYPE, 7 PRODUCT_ID, 8 CREATE_TIME 9 )10 <foreach item="item" index="index" collection="list" separator="union all">11 (12 SELECT 13 #{item.id},14 #{item.userId},15 #{item.businessType},16 #{item.productId},17 #{item.createdTime} 18 FROM DUAL19 )20 </foreach>21 </insert>
參考:
http://stackoverflow.com/questions/24956269/camel-2-13-1-mybatis-3-2-7-batch-insert-to-oracle-11g-table-ora-00933-sql-comma
mybatis批量插入資料到oracle