我有一张表X
,其中有一列BALANCE
。我有两个行ID和一个值amount
。有两个约束变量 - MAX_BALANCE
和MIN_BALANCE
。
我需要编写更新查询来更新列BALANCE
。第一行ID BALANCE
添加了amount
,amount
从第二行ID BALANCE
中减去。我需要确保BALANCE
始终保持在范围内。也就是说,MIN_BALANCE
< = BALANCE
< = MAX_BALANCE
。
如果更新的行数不等于2,我不应该更新一行然后回滚。更新查询应该更新两行(成功案例)或者根本不应该更新任何行。< / p>
我在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执行此操作?
答案 0 :(得分:1)
你需要自己加入你的桌子。第一个实例应该有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
答案 1 :(得分:0)
试试这个......
String sql = "UPDATE X x "
+ "SET x.balance = CASE "
+ "WHEN x.id = :rowId1 AND x.balance + :amount <= :MAX_BALANCE THEN (x.balance + :amount) "
+ "WHEN x.id = :rowId2 AND x.balance - :amount >= :MIN_BALANCE THEN (x.balance - :amount) "
+ "END "
+ "WHERE x.id = :rowId1 OR x.id = :rowId2";