【问题标题】:Pass nothing (not null) to the server if the argument is None如果参数为 None,则不向服务器传递任何内容(非 null)
【发布时间】:2014-04-09 08:00:55
【问题描述】:

我有一个模型:

case class MyModel(
  id: Pk[Long] = NotAssigned,
  startsAt: Option[DateTime] = None,
  addedAt: Option[DateTime] = None
) 

object MyModel {

// .....................
SQL("""
    INSERT INTO my_table(starts_at)
    VALUES ({startsAt})
    """
    ).on('startsAt -> newItem.startsAt).executeInsert()

}

startst_atadded_at 在 Postgresql 中的默认值为 now(),并且不允许在其中包含空值。它不会对addedAt 造成任何错误(因为我从不将它从客户端传递给服务器),但如果在newItem.startsAt 中未指定它,它确实会导致startsAt 的错误,因此等于@ 987654328@,因此,它被传递为null

org.postgresql.util.PSQLException: ERROR: null value in column "starts_at" violates not-null constraint

我想要的是能够在任何时候指定startsAt 并将其传递给服务器,这意味着如果我指定它,那么该值应该传递给服务器,如果不是 - 什么都没有 应该被传递并且服务器应该使用它的默认值 now()。我不想在客户端指定默认值,因为它已经在服务器的 db 级别设置了。

【问题讨论】:

  • 我不确定,但我认为唯一的解决方案是startsAt match { case Some(s) => "insert with {s}" case None => "insert without {s}" }Anorm 是一个简单的 JDBC 包装器。我怀疑你可以调整它不发送空字段
  • @serejja,是的,我认为你是对的。

标签: postgresql scala playframework playframework-2.2 anorm


【解决方案1】:

这个 SQL 修复怎么样:

insert into my_table(starts_at)
values (COALESCE({startsAt}, now())

更新:要求使用列的默认值

我所知道的让服务器在插入中使用列的默认值的唯一方法是在列列表中提及该列。例如(未测试):

startsAt.map { date =>
  SQL("""insert into my_table(starts_at) values({startsAt})""")
    .on('startsAt -> date)
    .execute()
}.orElse {
  SQL("""insert into my_table() values()""")
    .execute()
}

【讨论】:

  • postgres 是 coalesce({startsAt}, now())
  • 谢谢!我会修复答案
  • 我说,值“now()”已经在服务器上指定了。您的解决方案也在客户端使用 now() 。我可以使用 newItem.startsAt.getOrElse(DateTime.now()) 代替,因为它更简单。但我不想要这个。
  • SQL 中的 now() 将在服务器上执行,而不是在客户端。
  • 我想 Alex 的意思是他不想在架构和客户端代码中重复 now()。如果默认值更改,这将导致复杂化
猜你喜欢
  • 2019-06-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-22
  • 2021-03-01
  • 2018-07-23
  • 2016-04-01
  • 1970-01-01
相关资源
最近更新 更多