MyBatis操作Oracle批量插⼊ORA-00933:SQL命令未正确结
最近在使⽤MyBatis操作Oracle数据库的时候,进⾏批量插⼊数据,思路是封装⼀个List集合通过Myabtis
的foreach标签进⾏循环插⼊,可是搬照Mysql的批量插⼊会产⽣异常
  ### Error updating database.  Cause: java.sql.SQLSyntaxErrorException: ORA-00933: SQL 命令未正确结束
错误的写法如下
<insert id="insertExpenseItem" parameterType="List" >
insert into expenseItem values
<foreach collection="list" item="item" separator="," >
(
val,
syntaxerror是什么错误
#{pId},
#{pe},
#{item.amount},
#{item.itemDesc}
)
</foreach>
</insert>
捕捉到的SQL语句如下
- ==> Preparing: insert into expenseItem values ( val, ?, ?, ?, ? ) , ( val, ?, ?, ?, ? )
- ==> Parameters: 11(Integer), 1(String), 1111.0(Double), 2(String), 11(Integer), 3(String), 1111.0(Double),
2222(String)
即使在pl/sql上执⾏该语句依旧会报错!这样分析⼤概就是Oracle语法的问题了
⾸先在度娘上了MyBatis 之foreach插⼊的相关资料
具体如下:
foreach的主要⽤在构建in条件中,它可以在SQL语句中进⾏迭代⼀个集合。
foreach元素的属性主要有 item,index,collection,open,separator,close。
item表⽰集合中每⼀个元素进⾏迭代时的别名,index指定⼀个名字,⽤于表⽰在迭代过程中,每次迭代到的位置,open表⽰该语句以什么开始,separator表⽰在每次进⾏迭代之间以什么符号作为分隔符,close表⽰以什么结束,在使⽤foreach的时候最关键的也是最容易出错的就是collection属性,该属性是必须指定的,但是在不同情况下,该属性的值是不⼀样的,主要有⼀下3种情况:
1.如果传⼊的是单参数且参数类型是⼀个List的时候,collection属性值为list
2.如果传⼊的是单参数且参数类型是⼀个array数组的时候,collection的属性值为array
3.如果传⼊的参数是多个的时候,我们就需要把它们封装成⼀个Map了,当然单参数也可以封装成map
于是乎就有了上边不动脑,错误的写法了!!
⼜查了MyBatis操作Oracle的相关资料
得到结论:在Oracle的版本中,有⼏点需要注意的:
1.SQL中没有VALUES;
2.<foreach>标签中的(selece ..... from dual);
3.<foreach>标签中的separator的属性为"UNION ALL",将查询合并结果集。
正确的写法如下:
<insert id="insertExpenseItem" parameterType="List">
insert into expenseItem(itemId,expId,type,amount,itemDesc)
select val itemId,A.*
from(
<foreach collection="list" item="item" separator="union all" >
select
#{pId} expId,
#{pe} type,
#{item.amount} amount,
#{item.itemDesc} itemDesc
from dual
</foreach>
)A
</insert>
完美解决!
PS:
  注意不能把序列写在foeach⾥⾯的select⾥⾯!!按照我的正确写法进⾏照葫芦画瓢即可