場景是仁锯,別人給我傳一張表中的數(shù)據(jù)list锣杂,其中的數(shù)據(jù)有些是數(shù)據(jù)庫中有的,有些是新的缔杉,已經(jīng)有的我要更新锤躁,新的我要插入,oracle提供了merge into語句來實(shí)現(xiàn)這個(gè)功能
MERGE INTO [target-table] A USING [source-table sql] B ON([conditional expression] and [...]...)
WHEN MATCHED THEN
[UPDATE sql]
WHEN NOT MATCHED THEN
[INSERT sql]
- merge into沒有返回值或详,返回值只有insert,update郭计,delete三個(gè)基本的DML語句才有
- meige into只能把表A和表B進(jìn)行比較霸琴,要么表B是已經(jīng)存在的表,要么用select "常量" from dual來建立臨時(shí)的只有一條數(shù)據(jù)的表
原本打算用mybatis+foreach將list中的每一條數(shù)據(jù)建立臨時(shí)表和原有表進(jìn)行比較昭伸,如下
image.png
但是發(fā)現(xiàn)執(zhí)行中梧乘,如果有不止一條數(shù)據(jù)進(jìn)來,就會(huì)報(bào)如下錯(cuò)
sql injection violation, multi-statement not allow
image.png
可以看到,我的foreach选调,separator=";"夹供,也就是說我最后要執(zhí)行的是很多個(gè)sql,java不允許這樣做仁堪。
方法二(暫時(shí)采用的方法)
在java中哮洽,用foreach循環(huán),對list的每一條記錄merge into
在使用merge into的時(shí)候弦聂,有時(shí)候會(huì)報(bào)錯(cuò)
image.png
org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.type.TypeException: Could not set parameters for mapping: ParameterMapping{property='roomInfo.roomType', mode=IN, javaType=class java.lang.Object, jdbcType=null, numericScale=null, resultMapId='null', jdbcTypeName='null', expression='null'}. Cause: org.apache.ibatis.type.TypeException: Error setting null for parameter #5 with JdbcType OTHER . Try setting a different JdbcType for this parameter or a different jdbcTypeForNull configuration property. Cause: java.sql.SQLException: 無效的列類型: 1111
錯(cuò)在我沒有為變量指定類型鸟辅,識別出來的類型為other,所以當(dāng)這個(gè)字段為null時(shí)莺葫,插入不成功匪凉。解決辦法是指定類型,比如#{roomInfo.roomLayer,jdbcType=VARCHAR}
image.png
這里我只將有可能為null值的字段指定捺檬,其他沒管再层。
方法三
在數(shù)據(jù)庫中創(chuàng)建一個(gè)臨時(shí)表,將list插入數(shù)據(jù)庫堡纬,再將原表和臨時(shí)表進(jìn)行merge into树绩,最后將臨時(shí)表的記錄delete