使用Java PreparedStatement指示行更新没有变化的最佳方法

时间:2011-08-29 18:59:30

标签: java sql-server-2008 prepared-statement

我正在创建一个更新SQL Server 2008数据库中的行的方法。 SQL String看起来像这样:

private static final String UPDATE_ROW = 
    "UPDATE MyTable SET FieldOne = ?, FieldTwo = ? " +
    "WHERE IDField = ?";

当然,这是简化的。但问题是并非所有领域都必然会发生变化。我知道,使用直接SQL,您可以将字段名称放入值中,并且不会发生任何变化;但是,我不知道如何使用Java PreparedStatement

我可以通过为每一行调用每个字段的一个更新(最多十个)来解决它,但这只是很难看,我真的想避免它。谁能告诉我如何将字段名称作为参数值,或者至少给我一个干净的解决方案?

3 个答案:

答案 0 :(得分:1)

我无法找到一种方法来完成我所描述的内容,因此我最终阅读了我正在更新的内容的值并传递了这些值。

答案 1 :(得分:0)

您正试图避免为每次更新生成专门的声明。

这些字段是否相互关联?因为如果它们是相互关联的,则更新可以更好地保持场间一致性。因此,您需要首先读取值,然后将所有值都写回来 - 包括已更改的和未更改的值。

如果他们真的完全无关,那么就会同时提交一系列更新。

通常,最终会介于两者之间 - 存在相互关联的字段集群。例如,包含与BillingAddress相关的多个字段的Person记录。在这种情况下,请为每组相关字段准备一份声明。

如果您试图避免读取的成本(获取当前值),那么请考虑一个存储过程,其中未更改的字段值使用NULL进行编码。

如果您没有使用ORM,您还可以考虑使用光标ResultSet,逐个更新字段,然后使用updateRow()提交更改。见java.sql.ResultSet。要使用PreparedStatement执行与Javadoc相同的操作,您需要使用variant of Connection.prepareStatement(...)

答案 2 :(得分:0)

如果您创建了专门的UPDATE语句,声明已更改的列,那么效率会更高。

如果您始终更新所有列,则会产生大量开销,例如:更新索引列,这将导致相应的索引也被更新(并且没有实际需要)。

即使您指定UPDATE foo SET bar = bar,如果我没有弄错,也会发生这种情况。我不认为SQL Server会优化这些更新。