2013-08-02 18 views
1

我想基於其他列更新表的列,但看起來像我不能用updateWhere函數執行它。所以我嘗試使用rawSQl,但由於模糊的類型錯誤,它不起作用。當使用RawSql更新時模糊類型錯誤

getCalculateDeltaR :: personId -> Handler Html 
getCalculateDeltaR personId = do 

    goods <- runDB $ selectList [GoodPerson ==. personId] [] 

    forM goods $ \(Entity gid good) -> do 
     let aid = goodAsset good 
     asset <- runDB $ get404 aid 
     let mktValue = assetMktValue asset 
     runDB $ rawSql "UPDATE good SET delta = (? - orig_value) \ 
       WHERE person = ? AND asset = ?" 
       [toPersistValue mktValue, toPersistValue personId, toPersistValue aid] 

    defaultLayout $ do 
     $(widgetFile "calculateDelta") 

我得到以下錯誤,我嘗試添加?在UPDATE之後,但它沒有什麼區別。

Ambiguous type variable `a0' in the constraint: 
    (RawSql a0) arising from a use of `rawSql' 
Probable fix: add a type signature that fixes these type variable(s) 
In the second argument of `($)', namely 
    `rawSql 
... 
... 

我可以傳遞給rawSQL的參數已定義好,所以不知道是什麼導致了這個問題。有人能告訴我如何解決上述問題嗎?如果有更好的方法來更新基於其他列的列,也很想知道這一點。

謝謝!

回答

4

我不知道persistent不錯,但是這種類型的錯誤發生是因爲您將函數組合在一起,使得產生的消費而不被檢查。例如,如果您有功能f :: a -> (Int, c)g :: (Int, c) -> b,那麼g . f感覺應該是a -> b,但它實際上是一個錯誤,因爲GHC不知道應該是什麼c

解決此問題的方法是以c可以解析爲特定類型的方式檢查(Int, c)值。這通常通過手動類型註釋或使用asTypeOf來完成。

+1

太棒了!感謝您的建議。通過在我的rawSql語句的末尾添加:: Handler [Entity Good]來修復錯誤。我不知道什麼更新將完全返回,但看起來像給表的類型滿足編譯器,因爲我真的不關心任何返回值。 – Ecognium