Выполнить несколько инструкций INSERT в MyBatis для IBM DB2 - PullRequest
0 голосов
/ 24 мая 2019

Я пытаюсь выполнить несколько операторов INSERT через MyBatis для IBM DB2, используя Spring Boot (Java).

В XML

<insert id="insertIntoTempTmpCopyTo" parameterType="map">
   <foreach collection="list" item="lItem" separator=";">
      <foreach collection="data.keyList" item="rec" separator=";">
         <if test = "rec.sel and ((rec.keyType eq 'PPP'.toString())">
            INSERT INTO SESSION.MP_COPYTO(VP_ENCRP_PRC_RL_ID, PROC_CD, VER_KEY_SET_CD, TRNSLT_TP_CD, SET_INDEX_NUM, SET_MDK_DKI_NUM, PACKET_NUM)
            SELECT      
                '${lItem.EncrpRlId}' as ENCRP_RL_ID,
                '${rec.systemTo}' as PROC_CD,
                '${rec.keyType}' as KEY_SET_CD,
                '${rec.trnsltTpCd}' as TRNSLT_CD,
                '${rec.setTo}' as SET_INDEX,
                '${rec.dkiTo}' AS SET_NUM,

                <if test="lItem.packetNum != null">
                    ${lItem.packetNum} AS P_NUM
                </if>
                <if test="lItem.packetNum == null">
                    0 AS P_NUM
                </if>
            FROM SYSIBM.SYSDUMMY1
        </if>
    </foreach>
  </foreach>
  ;
</insert>

Используя это, я могу создать несколько вставокзаявления

 INSERT INTO SESSION.MP_COPYTO(ENCRP_RL_ID, PROC_CD, KEY_SET_CD, TRNSLT_CD, SET_INDEX, SET_NUM, P_NUM) 
 SELECT '500137' as ENCRP_RL_ID, 'DB' as PROC_CD, 'MDK' as KEY_SET_CD, '0' as TRNSLT_CD, '1' as SET_INDEX, '001' AS SET_NUM, 766456 AS P_NUM FROM SYSIBM.SYSDUMMY1 ; 

 INSERT INTO SESSION.MP_COPYTO(ENCRP_RL_ID, PROC_CD, KEY_SET_CD, TRNSLT_CD, SET_INDEX, SET_NUM, P_NUM) 
 SELECT '500137' as ENCRP_RL_ID, 'DB' as PROC_CD, 'MDK' as KEY_SET_CD, '0' as TRNSLT_CD, '2' as SET_INDEX, '002' AS SET_NUM, 766456 AS P_NUM FROM SYSIBM.SYSDUMMY1 ; 

Но когда я выполняю через Spring Boot JAVA, я могу вставить только одну строку

2019-05-24 09:36:51,094 DEBUG [SimpleAsyncTaskExecutor-1] : Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@123536e]
2019-05-24 09:36:51,094 DEBUG [SimpleAsyncTaskExecutor-1] : Fetched SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@123536e] from current transaction
2019-05-24 09:36:51,118 DEBUG [SimpleAsyncTaskExecutor-1] : ==>  Preparing: INSERT INTO SESSION.MP_COPYTO(ENCRP_RL_ID, PROC_CD, KEY_SET_CD, TRNSLT_CD, SET_INDEX, SET_NUM, P_NUM) SELECT '500137' as ENCRP_RL_ID, 'DB' as PROC_CD, 'MDK' as KEY_SET_CD, '0' as TRNSLT_CD, '1' as SET_INDEX, '001' AS SET_NUM, 766456 AS P_NUM FROM SYSIBM.SYSDUMMY1 ; INSERT INTO SESSION.MP_COPYTO(ENCRP_RL_ID, PROC_CD, KEY_SET_CD, TRNSLT_CD, SET_INDEX, SET_NUM, P_NUM) SELECT '500137' as ENCRP_RL_ID, 'DB' as PROC_CD, 'MDK' as KEY_SET_CD, '0' as TRNSLT_CD, '2' as SET_INDEX, '002' AS SET_NUM, 766456 AS P_NUM FROM SYSIBM.SYSDUMMY1 ;
2019-05-24 09:36:51,118 DEBUG [SimpleAsyncTaskExecutor-1] : ==> Parameters: 
2019-05-24 09:36:51,158 DEBUG [SimpleAsyncTaskExecutor-1] : <==    Updates: 1

Я не понимаю, почему это происходит.Я ищу место, чтобы установить для свойства allowMultipleQueries значение true, но я не могу найти.Есть ли способ, которым я мог бы установить его во время выполнения.

Это то, что я мог бы сделать.

Любые входные данные будут полезны.

Спасибо!

Ответы [ 2 ]

0 голосов
/ 04 июня 2019

я не знаком с IBM DB2, но вы можете изменить свой mapper.xml на что-то вроде этого

<insert id="insertIntoTempTmpCopyTo" parameterType="map">
    INSERT ALL  
    <foreach collection="list" item="element" index="index" >
        <foreach collection="data.keyList" item="rec">
            INTO SESSION.MP_COPYTO(VP_ENCRP_PRC_RL_ID, PROC_CD, VER_KEY_SET_CD, TRNSLT_TP_CD, SET_INDEX_NUM, SET_MDK_DKI_NUM, PACKET_NUM)
            VALUES
            (
                #{lItem.EncrpRlId},
                #{rec.systemTo},
                #{rec.keyType},
                #{rec.trnsltTpCd},
                #{rec.setTo},
                #{rec.dkiTo},
                <choose>
                    <when test="lItem.packetNum != null">
                        #{lItem.packetNum}
                    </when>
                    <otherwise>
                        0
                    </otherwise>
                </choose>
            )
        </foreach>
    </foreach>
    SELECT * FROM dual
    </insert>
</mapper>

SELECT * FROM dual в конце очень важно

или вы измените свой mapper.xml на

<insert id="insertIntoTempTmpCopyTo" parameterType="map">
    -- Change the delimiter from ';' to '§'
    -- @DELIMITER §

    -- removed separator=";"
    <foreach collection="list" item="lItem">

        -- removed separator=";"
        <foreach collection="data.keyList" item="rec">
            <if test = "rec.sel and ((rec.keyType eq 'PPP'.toString())">
                INSERT INTO SESSION.MP_COPYTO(VP_ENCRP_PRC_RL_ID, PROC_CD, VER_KEY_SET_CD, TRNSLT_TP_CD, SET_INDEX_NUM, SET_MDK_DKI_NUM, PACKET_NUM)
                SELECT      
                  #{lItem.EncrpRlId} AS ENCRP_RL_ID,
                  #{rec.systemTo}    AS PROC_CD,
                  #{rec.keyType}     AS KEY_SET_CD,
                  #{rec.trnsltTpCd}  AS TRNSLT_CD,
                  #{rec.setTo}       AS SET_INDEX,
                  #{rec.dkiTo}       AS SET_NUM,

                  <choose>
                      <when test="lItem.packetNum != null">
                          #{lItem.packetNum} AS P_NUM
                      </when>
                      <otherwise>
                          0  AS P_NUM
                      </otherwise>
                  </choose>
                  FROM SYSIBM.SYSDUMMY1

                  -- separator inserted
                  ;
            </if>
        </foreach>
    </foreach>
    -- Change the delimiter back to ';'
    -- @DELIMITER ;
</insert>

изменяя mybatis-delimiter с ; на что-то другое, что не отображается в вашем выражении, как §, вы можете выполнять sql-скрипты с разделителями-точками с разделителями

0 голосов
/ 25 мая 2019

Вы не указали версии, но Db2 может поддерживать многострочный синтаксис вставки.
Кажется, есть некоторые вариации в соответствии с этой веткой , хотя.

Я только что протестировал следующий синтаксис с Db2 LUW 11, и он сработал.

INSERT INTO table (col1, col2) VALUES (?, ?), (?, ?)

Используя этот синтаксис, оператор можно записать следующим образом:

<insert id="insertIntoTempTmpCopyTo" parameterType="map">
  INSERT INTO SESSION.MP_COPYTO(VP_ENCRP_PRC_RL_ID,
    PROC_CD, VER_KEY_SET_CD, TRNSLT_TP_CD,
    SET_INDEX_NUM, SET_MDK_DKI_NUM, PACKET_NUM) VALUES
  <trim suffixOverrides=",">
    <foreach collection="list" item="lItem">
      <foreach collection="data.keyList" item="rec">
        <if test="rec.sel and (rec.keyType eq 'PPP'.toString())">
          (#{lItem.EncrpRlId}, #{rec.systemTo}, #{rec.keyType},
            #{rec.trnsltTpCd}, #{rec.setTo}, #{rec.dkiTo},
          <if test="lItem.packetNum != null">
            #{lItem.packetNum}
          </if>
          <if test="lItem.packetNum == null">
            0
          </if>
          ),
        </if>
      </foreach>
    </foreach>
  </trim>
</insert>
  • Элемент <trim /> удаляет лишнюю запятую.
  • Вы должны использовать #{} вместо ${}, когда это возможно. См. FAQ .
...