Mybatis結合Oracle的foreach insert批量插入報錯!

        最近作一個批量導入的需求,將多條記錄批量插入數據庫中。解決思路:在程序中封裝一個List集合對象,而後把該集合中的實體插入到數據庫中,由於項目使用了MyBatis,因此打算使用MyBatis的foreach功能進行批量插入。期間遇到了「SQL 命令未正確結束 」的錯誤,最終解決,記錄下來供之後查閱和學習。html

        首先,在網上參考了有關Mybatis的foreach insert的資料,具體以下:java

        foreach的主要用在構建in條件中,它能夠在SQL語句中進行迭代一個集合。sql

        foreach元素的屬性主要有 item,index,collection,open,separator,close。數據庫

        item表示集合中每個元素進行迭代時的別名,index指定一個名字,用於表示在迭代過程當中,每次迭代到的位置,open表示該語句以什麼開始,separator表示在每次進行迭代之間以什麼符號做爲分隔符,close表示以什麼結束,在使用foreach的時候最關鍵的也是最容易出錯的就是collection屬性,該屬性是必須指定的,可是在不一樣狀況 下,該屬性的值是不同的,主要有一下3種狀況:數組

        1.若是傳入的是單參數且參數類型是一個List的時候,collection屬性值爲listoracle

        2.若是傳入的是單參數且參數類型是一個array數組的時候,collection的屬性值爲arrayapp

        3.若是傳入的參數是多個的時候,咱們就須要把它們封裝成一個Map了,固然單參數也能夠封裝成map學習

        而後,照葫蘆畫瓢寫了以下的xml文件,xml

xxxMapper.xml文件:htm

<insert id="addSupCity" parameterType="java.util.List">
    <selectKey keyProperty="cityId" order="BEFORE" resultType="String">
        <![CDATA[SELECT SEQ_OCL_SUPCITY.NEXTVAL FROM dual]]>
    </selectKey>
    INSERT INTO T_OCL_SUPCITY
    (CITY_ID,CITY_CODE, CITY_NAME, AREA_DESC, SUP_ID, STAT)
    VALUES 
    <foreach collection="list" item="item" index="index" separator=",">     
      (
        #{item.cityId,jdbcType=VARCHAR},
        #{item.cityCode,jdbcType=VARCHAR},
        #{item.cityName,jdbcType=VARCHAR},
        #{item.areaDesc,jdbcType=VARCHAR},
        #{item.supId,jdbcType=VARCHAR},
        #{item.stat,jdbcType=VARCHAR}
      )
    </foreach>
</insert>

        可是運行起來後就一直報錯,報錯信息以下:

### SQL: INSERT INTO T_OCL_SUPCITY
(CITY_ID,CITY_CODE, CITY_NAME, AREA_DESC, SUP_ID, STAT) VALUES (?,?,?,?,?),(?,?,?,?,?)
### Cause: java.sql.SQLSyntaxErrorException: ORA-00933: SQL 命令未正確結束

        把SQL複製出來在PL/SQL中運行也是報一樣的錯,如上也能夠看出,使用批量插入執行的SQL語句等價於: INSERT INTO T_OCL_SUPCITY (CITY_ID,CITY_CODE, CITY_NAME, AREA_DESC, SUP_ID, STAT) VALUES (?,?,?,?,?),(?,?,?,?,?),而在oracle中用insert into xxx values (xxx,xxx),(xxx,xxx) 這種語法是通不過的 。再回過頭去看那篇文章,發現這是適用於MySQL的,不適用於Oracle,所以把xml文件修改一下:

<insert id="addSupCity" parameterType="java.util.List">
      INSERT INTO T_OCL_SUPCITY
  (CITY_ID,CITY_CODE, CITY_NAME, AREA_DESC, SUP_ID, STAT)
SELECT SEQ_OCL_SUPCITY.NEXTVAL CITY_ID, A.*
FROM(
<foreach collection="list" item="item" index="index" separator="UNION ALL">
 SELECT 
       #{item.cityCode,jdbcType=VARCHAR} CITY_CODE,
       #{item.cityName,jdbcType=VARCHAR} CITY_NAME,
       #{item.areaDesc,jdbcType=VARCHAR} AREA_DESC,
       #{item.supId,jdbcType=VARCHAR} SUP_ID,
       #{item.stat,jdbcType=VARCHAR} STAT
     FROM dual
   </foreach>
   )A
  </insert>

        運行經過。在Oracle的版本中,有幾點須要注意的:

        1.SQL中沒有VALUES;

        2.<foreach>標籤中的(selece ..... from dual);

        3.<foreach>標籤中的separator的屬性爲"UNION ALL",將查詢合併結果集。

相關文章
相關標籤/搜索