我循环遍历一组对象,将它们插入到我的PostgreSQL数据库中,如下所示:
sql.withTransaction {
try {
sql.withBatch(1000, 'insert into category (id, version, name, parent_id) values (:id, :version, :name, :parent_id);') { stmt ->
categoryInserts.each {
try {
stmt.addBatch([id: it.id, version: 0, name: it.name, parent_id: it.parent?.id])
} catch (SQLException e) {
log.error("Category ${it.name} with parent ${it.parent?.id} could not be inserted.")
}
}
}
} catch (BatchUpdateException e) {
log.error("Categories could not be inserted.")
}
sql.commit()
}
类别表上有唯一约束(name,parent_id)。如果违反约束,程序将捕获BatchUpdateException,并且不会插入后续对象。不幸的是,执行addBatch-method时不会抛出异常。
有没有办法继续使用withBatch语句,以便忽略重复项并插入新记录?对我来说,批量插入不提供这种行为似乎很奇怪。
答案 0 :(得分:0)
我能够用Alexandros评论中提到的帖子来解决这个问题。解决方案现在看起来像这样:
sql.withTransaction {
try {
sql.withBatch(1000, 'insert into category (id, version, name, parent_id) ' +
'select :id, :version, :name, :parent_id ' +
'where not exists (select name, parent_id from category where name = :name and parent_id = :parent_id);') { stmt ->
categoryInserts.each {
try {
stmt.addBatch([id: it.id, version: 0, name: it.name, parent_id: it.parent?.id])
} catch (SQLException e) {
log.error("Category ${it.name} with parent ${it.parent?.id} could not be inserted.")
}
}
}
} catch (BatchUpdateException e) {
log.error("Categories could not be inserted.", e)
}
sql.commit()
}
请注意,这是通过SQL的postgresql方言解决的。对于其他DBMS,在withBatch方法中使用SQL过程可能是一种有用的方法。
如果有人知道使用标准SQL的方法,请给我一个提示。