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="," >
        (
            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里面!!按照我的正確寫法進行照葫蘆畫瓢即可

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM