2

我正在尝试insert into ... on duplicate key update使用play-slick. 您可以在下面的代码中看到我正在使用的 SQL:

def recordGuess(date: LocalDate, correctBlah: Blah, incorrectBlah: Blah, isCorrect: Boolean)(implicit s: Session) {
  val correctIncrement = if(isCorrect) 1L else 0L
  sqlu"insert into stats (date, correctBlah, incorrectBlah, impressions, guesses, correct) values ($date, $correctBlah, $incorrectBlah, 1, 1, $correctIncrement) on duplicate key update guesses = guesses + 1, correct = correct + $correctIncrement".first
}

这个单一的更新语句只使用一个查询和一个唯一索引来完成两个查询的工作。sql问题是 Slick 在使用原始 SQL ( and sqlu)时似乎不支持隐式字段转换。我从上面得到的错误如下:

could not find implicit value for parameter pconv: scala.slick.jdbc.SetParameter[(org.joda.time.LocalDate, models.Blah.Blah, models.Blah.Blah)]

尽管com.github.tototoshi.slick.JodaSupport._用于支持LocalDate. 我还有一个Blah类型的隐式转换器,它使用普通选择工作。在这个问题上没有人能帮我解决这个问题:Scala Slick implicit conversion of multiple types in raw SQL query

在上面的链接问题中,我能够创建一个解决方法,但我不知道如何为该insert into ... on duplicate key update问题创建一个解决方法。有任何想法吗?谢谢。

更新:

这似乎是我能想到的最好的,但它非常糟糕,需要多个查询:

def findByDateAndBlahs(date: LocalDate, correctBlah: Blah, incorrectBlah: Blah)(implicit s: Session): Option[Stat] = {
  Query(Stats).where(_.date === date).where(_.correctBlah === correctBlah).where(_.incorrectBlah === incorrectBlah).run.headOption
}

def recordGuess(date: LocalDate, correctBlah: Blah, incorrectBlah: Blah, isCorrect: Boolean)(implicit s: Session) {
  val correctIncrement = if(isCorrect) 1L else 0L
  this.findByDateAndBlahs(date, correctBlah, incorrectBlah) match {
    case Some(stat) => {
      val updatedStat = new Stat(stat.id, stat.date, stat.correctBlah, stat.incorrectBlah, stat.impressions, stat.guesses + 1, stat.correct + correctIncrement)
      Stats.where(_.id === stat.id).update(updatedStat)
    }
    case None => this.insert(new Stat(None, date, correctBlah, incorrectBlah, 1L, 1L, correctIncrement))
}
4

0 回答 0