【问题标题】:Null value comparision in slick光滑的空值比较
【发布时间】:2014-12-19 09:00:47
【问题描述】:

我遇到了可空列比较的问题。

如果某些列是Option[T],我想知道如何将这些列上的=== 操作转换为sql。 有两种可能性:空值(在 scala 中为 None )和非空值。 在空值的情况下,sql应该使用is而不是=。 但是在以下情况下 slick 无法正确处理它。

这里是代码(带有H2数据库):

object Test1 extends Controller {


  case class User(id: Option[Int], first: String, last: String)

  class Users(tag: Tag) extends Table[User](tag, "users") {
    def id = column[Int]("id",O.Nullable)
    def first = column[String]("first")
    def last = column[String]("last")
    def * = (id.?, first, last) <> (User.tupled, User.unapply)
  }
  val users = TableQuery[Users]


  def find_u(u:User) =  DB.db.withSession{ implicit session =>
    users.filter( x=> x.id === u.id && x.first === u.first && x.last === u.last ).firstOption

  }

  def t1 = Action {
    DB.db.withSession { implicit session =>
      DB.createIfNotExists(users)

      val u1 = User(None,"123","abc")
      val u2 = User(Some(1232),"123","abc")

      users += u1
      val r1 = find_u(u1)
      println(r1)
      val r2 = find_u(u2)
      println(r2)

    }
    Ok("good")
  }
}

我打印出 sql。这是第一个find_u 的结果。

[debug] s.s.j.J.statement - Preparing statement: select x2."id", x2."first", x2."last" from "users" x2 where (
(x2."id" = null) and (x2."first" = '123')) and (x2."last" = 'abc')

请注意(x2."id" = null) 此处不正确。应该是(x2."id" is null)

更新:

是否可以仅以自动方式比较非空字段?忽略那些空列。 例如。对于User(None,"123","abc"),只做where (x2."first" = '123')) and (x2."last" = 'abc')

【问题讨论】:

  • 不要使用列[Int]("id",O.Nullable)。正确的是 column[Option[Int]]("id")。否则你可能会遇到异常。
  • 嗨@cvogt,谢谢你的建议。但是 column[Option[Int]]("id") 不能解决我的问题。 sql 保持不变。
  • 没错,这就是为什么我也写了一个答案:)

标签: slick slick-2.0


【解决方案1】:

Slick 使用三值逻辑。这显示了何时涉及可空列。在这方面,它不遵循 Scala 语义,而是使用 SQL 语义。所以(x2."id" = null) 在这些设计决策下确实是正确的。要进行严格的 NULL 检查,请使用 x.id.isEmpty。为了严格比较做

(if(u.id.isEmpty) x.id.isEmpty else (x.id === u.id))

更新:

仅在用户 id 为非空时进行比较

(u.id.isEmpty || (x.id === u.id)) && ...

【讨论】:

  • 谢谢 cvogt。我更新了这个问题。是否可以只比较非空字段?
  • 更新了答案。但可能最好的是我已经建议的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-28
相关资源
最近更新 更多