一、背景
在代碼中有一段形如下面的SQL,數據庫是Oracle的
INSERT INTO IPAM.T_SEARCHDETAIL (ID, UNIQUEPART, LOCATIONID, PARANAME, RESULTSTRING, RESULTVALUE, RESULTDATE, SEARCHNO, TYPENO, TYPEVAR, RESULTSTATE) SELECT seq_searchdetail.NEXTVAL, CD.* FROM (SELECT '@F01R20D338@00101432@0204@20200923@125348@@', '00000000531500900001100010001', 'POS2LeftDistance', null, 2.352403, '2020-10-16 00:00:03.454', 1145, null TYPENO, null TYPEVAR, null RESULTSTATE FROM DUAL UNION all SELECT '@F01R20D338@00101432@0204@20200923@125348@@', '00000000531500900001100010001', 'GlueTimeOut', '0', null, '2020-10-16 00:00:03.454', 1145, null TYPENO, null TYPEVAR, null RESULTSTATE --.........還有大約1000多個union在一起的Selct語句
FROM DUAL) CD;
這條語句一般情況下都是正常執行的。因為之前每次執行的時候都滿足RESULTSTRING這個字段的數值都是非數字字符串,最近這條SQL一直報ORA-01790
數據量比較大,調試起來比較困難,每次執行都需要3分鍾左右。搞來搞去搞了一個晚上還是無法解決。最后縮小數據比例,加快調試進度。Mybatis用log4j打印在控制台的SQL語句又是參數和值分開的,又給IDEA安裝了mybatis log plugin插件,調試才順利了一些。最后猜測有可能是字符串類型的數字在select * from dual的時候被轉成了數字。
二、措施
Mybatis XML配置文件
<insert id="insertSearchdetailBatch" parameterType="java.util.List" useGeneratedKeys="false"> INSERT INTO IPAM.T_SEARCHDETAIL(ID,UNIQUEPART,LOCATIONID,PARANAME,RESULTSTRING,RESULTVALUE,RESULTDATE,SEARCHNO,TYPENO,TYPEVAR,RESULTSTATE) SELECT seq_searchdetail.NEXTVAL,CD.* FROM ( <foreach collection="list" index="index" item="item" separator="union all"> SELECT #{item.uniquepart} ,#{item.locationid} ,#{item.paraname} ,#{item.resultstring} ,#{item.resultvalue} ,#{item.resultdate} , #{item.searchno} ,#{item.typeno} TYPENO,#{item.typevar} TYPEVAR,#{item.resultstate} RESULTSTATE FROM DUAL </foreach> )CD </insert>
#{item.resultstring} 改成#{item.resultstring,jdbcType=VARCHAR}
#{item.resultvalue} 改成#{item.resultvalue,jdbcType=FLOAT}
問題得到解決
<insert id="insertSearchdetailBatch" parameterType="java.util.List" useGeneratedKeys="false"> INSERT INTO IPAM.T_SEARCHDETAIL(ID,UNIQUEPART,LOCATIONID,PARANAME,RESULTSTRING,RESULTVALUE,RESULTDATE,SEARCHNO,TYPENO,TYPEVAR,RESULTSTATE) SELECT seq_searchdetail.NEXTVAL,CD.* FROM ( <foreach collection="list" index="index" item="item" separator="union all"> SELECT #{item.uniquepart} ,#{item.locationid} ,#{item.paraname} ,#{item.resultstring,jdbcType=VARCHAR} ,#{item.resultvalue,jdbcType=FLOAT} ,#{item.resultdate} , #{item.searchno} ,#{item.typeno} TYPENO,#{item.typevar} TYPEVAR,#{item.resultstate} RESULTSTATE FROM DUAL </foreach> )CD </insert>