2016-12-02 38 views
1

我有一個表X,它有一列BALANCE。我有兩個行ID和值amount。有兩個約束變量 - MAX_BALANCEMIN_BALANCE根據兩種不同的約束更新兩行

我需要編寫一個更新查詢來更新列BALANCE。第一行ID BALANCEamount相加,並且amount從第二行ID的BALANCE中減去。我需要確保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執行此操作?

回答

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"; 
+0

不,它不起作用。當一個餘額達到負值時,它將得到'null'值。 –

+0

如果rowId2沒有足夠的餘額,那麼你需要做什麼? –

+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 
+0

這幾乎可行。我修改了這樣的查詢, 'update x x1 join x x2 set x1.balance = x1.balance +:amount, x2.balance = x2.balance-:amount where x1.id =:rowid1 and x2。 id = rowid2和x1.balance +:金額<=:MAX_BALANCE和x2.balance-:金額= =:MIN_BALANCE',現在它工作。 –

+0

但問題是,查詢不適用於Hibernate JPQL。 我收到以下錯誤。 java.lang.IllegalArgumentException:org.hibernate.hql.internal.ast.QuerySyntaxException:期待「set」,找到'JOIN',因爲JPA 2不支持這個。我不想使用nativeQuery。 –

+0

然後嘗試使用逗號代替單詞連接。 – Shadow