Java RFC程序向SQL表插入SAP数据时如何避免重复行插入
看起来你遇到的问题是SQL插入语句的语法错误,没法正确跳过已存在的主键数据。咱们一步步来解决这个问题:
首先,你原来的SQL写法是不对的——INSERT ... NOT IN (...) VALUES这种语法不符合SQL规范,正确的思路是先筛选出目标表中不存在的主键数据,再执行插入。下面根据不同的数据库类型,给你两种常用的解决方案:
方案1:MySQL数据库(最简洁高效)
如果你的目标SQL数据库是MySQL,而且ITPITP已经被设置为表的主键,那么可以用ON DUPLICATE KEY UPDATE语法,遇到重复主键时直接跳过插入:
修改你的Java代码中的SQL构建部分:
StringBuilder sbQuery = new StringBuilder( "INSERT INTO ITPMAST(ITPITP,ITPNAM,ITPSCT,ITPACTYN) VALUES" ); // 循环添加批量插入的参数占位符 for (int i = 0; i < table.getNumRows(); i++) { sbQuery.append("(?,?,?,?),"); } // 移除最后一个多余的逗号 sbQuery.deleteCharAt(sbQuery.length() - 1); // 添加跳过重复的逻辑:主键冲突时执行无意义的更新,相当于跳过 sbQuery.append(" ON DUPLICATE KEY UPDATE ITPITP = ITPITP;"); qex.setUpdateQuery(sbQuery.toString()); // 参数绑定部分保持不变 elements.clear(); String strPattern = "^0+(?!$)"; for (int i = 0; i < table.getNumRows(); i++) { table.setRow(i); elements.add(table.getString("MATNR").replaceAll(strPattern, "")); elements.add(table.getString("MAKTX")); elements.add(table.getString("MATKL")); elements.add("Y"); }
原理:当插入的行中ITPITP值已经存在于表中时,会触发主键冲突,ON DUPLICATE KEY UPDATE ITPITP = ITPITP只是把主键值设为本身,不会改变任何数据,数据库会自动跳过这条重复的插入请求,其他非重复数据正常插入。
方案2:跨数据库通用方案(支持SQL Server、Oracle等)
如果你的数据库不是MySQL,或者需要更通用的写法,可以用INSERT ... SELECT + NOT EXISTS的组合,先过滤掉已存在的数据再插入:
修改SQL构建部分如下:
StringBuilder sbQuery = new StringBuilder( "INSERT INTO ITPMAST(ITPITP,ITPNAM,ITPSCT,ITPACTYN) " + "SELECT temp.itpitp, temp.itpnam, temp.itpsct, temp.itpactyn " + "FROM (VALUES " ); // 循环添加批量数据的占位符 for (int i = 0; i < table.getNumRows(); i++) { sbQuery.append("(?,?,?,?),"); } sbQuery.deleteCharAt(sbQuery.length() - 1); // 添加过滤逻辑:只插入目标表中不存在的ITPITP数据 sbQuery.append(") AS temp(itpitp, itpnam, itpsct, itpactyn) " + "WHERE NOT EXISTS (" + " SELECT 1 FROM ITPMAST WHERE ITPMAST.ITPITP = temp.itpitp" + ");"); qex.setUpdateQuery(sbQuery.toString()); // 参数绑定部分和你原来的代码完全一致,无需修改 elements.clear(); String strPattern = "^0+(?!$)"; for (int i = 0; i < table.getNumRows(); i++) { table.setRow(i); elements.add(table.getString("MATNR").replaceAll(strPattern, "")); elements.add(table.getString("MAKTX")); elements.add(table.getString("MATKL")); elements.add("Y"); }
原理:先把所有要插入的数据放到一个临时数据集temp里,然后通过NOT EXISTS检查每个ITPITP是否已经存在于ITPMAST表中,只插入不存在的那些行。
关键注意事项
- 确保
ITPITP确实被设置为ITPMAST表的主键(或者至少是唯一约束),这样数据库才能准确识别重复数据。 - 如果是Oracle数据库,上面的通用方案需要调整临时表的写法,把
VALUES换成SELECT ... FROM DUAL的组合,比如每一行写成SELECT ?, ?, ?, ? FROM DUAL UNION ALL。
内容的提问来源于stack exchange,提问作者D.Madu
相关产品推荐
相关产品推荐

