一、背景
在代碼中有一段形如下面的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>
