2017-05-30 71 views
0

这可能是非常愚蠢的问,但我面临这种情况:如何在由主键违规引起的BatchUpdateException之后继续插入行?

我有一个表,我填充每次用户发送请求时,我在一个字段上使用日期(一个日期)从我插入的最后一行。问题是,我插入的最后一行总是尝试插入本身,因为它在我正在考虑的范围内。我知道一个解决方案可能只是在最后一行添加一两分钟,但是从这个问题出发。 我怎样才能在java中,使用PreparedStatement和批处理插入多行,跳过发送给我那个PRIMARY_KEY_VIOLATION异常,并继续插入那些没问题的? 我的意思是,例如,我在我的表中有一行25的值“runner”,这是我的主键,然后我想要插入这些行: (25,26,27) 25值不能被插入,所以我想捕捉异常,并继续插入26和27值。 这可能吗?

我感谢您的帮助和评论。先谢谢你!

+0

请参阅'BatchUpdateException' API。你所提出的建议可能会成为可能,但会非常丑陋。避免PK违规。创建一个序列,以便您可以“插入到表T SELECT MYSEQUENCE.NEXTVAL,OTHER_FIELD1,OHTER_FIELD2 WHERE ... –

+0

@AndrewS - 使用序列不能解决问题。确定它会生成一个唯一的值,但您刚刚插入了重复的记录使用无意义的技术密钥 – APC

+0

问题是,为什么选择已插入的行?当然,您需要解决的问题是获取有效的数据源,而不是处理数据目标中的异常。 – APC

回答

0

这并不完全清楚你想要达到的目标。数据库架构,代码和示例可能会有所帮助。但是从我的理解,我有以下提示:

  • 想想你主键

    • 一个技术关键应该是唯一的无需任何编程(如审判&错误...)。时间戳通常不符合该标准。您的数据库或GUID序列数据类型是一个不错的选择,因为它们只是用于此目的。

    • 一个非介绍技术关键应该代表整行特定行。日期/时间戳可能是一个可接受的关键,用于表示日历应用程序或特定实例中的某一天。时间戳通常不代表“用户请求”。

  • 想想交易:数据库通常强调原子,交易操作。如果部分操作失败,则必须回滚整个交易。 正如AndrewS指出的那样,在BatchUpdateException之后继续批量处理可能(取决于驱动程序),但这绝对是不是一个好的做法。这是一种代码味道,表明你做错了第一位。

  • 避免异常:使用异常的控制流也被认为是一个代码味道(见例如Java: Exceptions as control flow?与约书亚布洛赫的“有效的Java”参考项目57)。在尝试操作之前检查导致异常的情况通常是首选。或者如APC指出的那样:如果您知道您的代码会返回您插入的最后一行,为什么不直接从插入语句中删除它?