我有一个表X
,其中有一列BALANCE
。我有两个行 ID 和一个值 amount
。有两个约束变量 - MAX_BALANCE
和 MIN_BALANCE
。
我需要编写一个更新查询来更新列 BALANCE
。第一行 id 的 BALANCE
加上 amount
,第二行 id 的 BALANCE
减去 amount
。我需要确保 BALANCE
始终保持在范围内。也就是说,MIN_BALANCE
<= BALANCE
<= MAX_BALANCE
。
如果更新的行数不等于 2,我不应该更新一行然后回滚。更新查询应该更新两行(成功案例)或者根本不更新任何行。
我在 Java 中使用 Hibernate,这里是我试过的查询。它不适用于成功案例。
String sql = "UPDATE X x "
+ "SET x.balance = CASE "
+ "WHEN x.id = :rowId1 THEN (x.balance + :amount) "
+ "WHEN x.id = :rowId2 THEN (x.balance - :amount) "
+ "END "
+ "WHERE x.id IN :ids "
+ "AND ((x.id = :rowId1 AND x.balance + :amount <= :MAX_BALANCE) "
+ "OR (x.id = :rowId2 AND x.balance - :amount >= :MIN_BALANCE))";
Query query = entityManager.createQuery(sql);
List<BigInteger> ids = Arrays.asList(new BigInteger(rowId1), new BigInteger(rowId2));
int rows = query.setParameter("amount", amount)
.setParameter("ids", ids)
.setParameter("rowId1", new BigInteger(rowId1))
.setParameter("rowId2", new BigInteger(rowId2))
.setParameter("MAX_BALANCE", new Float(MAX_BALANCE))
.setParameter("MIN_BALANCE", new Float(MIN_BALANCE))
.executeUpdate();
我不想检查 rows == 1
是否抛出异常。更新查询应始终确保行将采用 0 或 2 的值。
或者有没有一种方法可以根据 Hibernate 中的 Criteria Update 执行此操作?
最佳答案
你需要自己加入你的 table 。第一个实例应该有 rowid1 的记录,第二个实例应该有 rowid2 的记录。这样您就可以一次性查看两条记录的余额,并决定是否更新。
update x x1 join x x2
set x1.balance=if(x1.balance+:amount <= :MAX_BALANCE,x1.balance+:amount, x1.balance),
x2.balance=if(x2.balance-:amount >= :MIN_BALANCE,x2.balance-:amount, x2.balance)
where x1.id=:rowid1 and x2.id=rowid2
关于java - 根据两个不同的约束更新两行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40925955/