阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

MyBatis操作Oracle批量插入 ORA-00933: SQL 命令未正确结束

127次阅读
没有评论

共计 1919 个字符,预计需要花费 5 分钟才能阅读完成。

最近在使用 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 里面!!按照我的正确写法进行照葫芦画瓢即可

MyBatis 操作 Oracle 批量插入 ORA-00933: SQL 命令未正确结束

更多 Oracle 相关信息见 Oracle 专题页面 https://www.linuxidc.com/topicnews.aspx?tid=12

正文完
星哥说事-微信公众号
post-qrcode
 
星锅
版权声明:本站原创文章,由 星锅 2022-01-22发表,共计1919字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中