zoukankan      html  css  js  c++  java
  • 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>

    注意不能把序列写在foeach里面的select里面!!按照我的正确写法进行照葫芦画瓢即可

    还要注意 <insert id="insert_" useGeneratedKeys="false">

    </insert>
    批量插入时,如果没有主键,一定要显式指定useGeneratedKeys为false,否则会报: SQL 命令未正确结束

  • 相关阅读:
    Github开始强制使用PAT(Personal Access Token)了
    STM32F401的外部中断EXTI
    STM32F401的PWM输出
    STM32F103和STM32F401的ADC多通道采集DMA输出
    nRF24L01无线模块笔记
    51单片机(STC89C52)在Ubuntu下的开发
    51单片机(STC89C52)的中断和定时器
    51单片机的软件和硬件PCA/PWM输出
    Zadig 云原生持续交付 面向开发者设计的开源、高可用 CI/CD
    人生 乐观 悲观 英雄
  • 原文地址:https://www.cnblogs.com/itzfz/p/15073318.html
Copyright © 2011-2022 走看看