最近在使用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="," > ( seq_item.nextval, #{item.expId}, #{item.type}, #{item.amount}, #{item.itemDesc} ) </foreach> </insert>
捕捉到的SQL語句如下
- ==> Preparing: insert into expenseItem values ( seq_item.nextval, ?, ?, ?, ? ) , ( seq_item.nextval, ?, ?, ?, ? )
- ==> 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 seq_item.nextval itemId,A.* from( <foreach collection="list" item="item" separator="union all" > select #{item.expId} expId, #{item.type} type, #{item.amount} amount, #{item.itemDesc} itemDesc from dual </foreach> )A </insert>
完美解決!
PS:
注意不能把序列寫在foeach里面的select里面!!按照我的正確寫法進行照葫蘆畫瓢即可