比较日期(如果不为空)

时间:2019-01-13 10:45:03

标签: java postgresql

我需要找到所有创建日期为X的记录。X是sql.Timestamp,可能为null,在这种情况下,我只想返回所有记录。所以我尝试了:(createdAfter是时间戳)

import scala.language.higherKinds

object Test {
    trait Expr[F[_]] {
        def const(i: Int): F[Int]
        def lam[A, B](f: F[A] => F[B]): F[A => B]
        def app[A, B](f: F[A => B], a: F[A]): F[B]
        def add(x: F[Int], y: F[Int]): F[Int]
    }

    type Id[A] = A

    object Interp extends Expr[Id] {
        override def const(i: Int): Id[Int] = i
        override def lam[A, B](f: Id[A] => Id[B]): Id[A => B] = f
        override def app[A, B](f: Id[A => B], a: Id[A]): Id[B] = f(a)
        override def add(x: Id[Int], y: Id[Int]): Id[Int] = x + y
    }

    def testVal[F[_]: Expr]: F[Int] = {
        implicit val f = implicitly[Expr[F]]
        f.app(
            f.lam[Int, Int](
                x => f.add(x, f.const(1))),
            f.const(10)
        )
    }

    def main(args: Array[String]): Unit = {
        val x = testVal(Interp)
        println(x)
    }
}

但是我得到的只是

Interp

但是,如果我在检查任意int为null的地方执行相同的查询:

testVal

然后它起作用。怎么了?

2 个答案:

答案 0 :(得分:0)

如果要坚持这样的本机查询,没有简单的解决方案。 null值将转换为bytea值。例如,请参见thisthis

该值很难转换或与timestamp值进行比较。

问题不在于第一次比较,而是通过合并来解决的,例如:

COALESCE(:createdAfter) ISNULL

因为在实际值之间没有比较,因此数据类型无关紧要。但是比较

sometimestamp::timestamp > null::bytea(播放只是为了显示实际类型,因此无法正常工作)

在过程和异常处理等方面可能还需要更多逻辑,不确定。

因此,如果您无法选择JPQL或CriteriaQueries,则只能选择以下错误的方法:

  • 通过字符串串联或类似方式设置参数来构造查询(不知道,不确定是否真的有用)
  • 使用PreparedStatement查询,更多的代码和精力
  • 如果使用的是Hibernate,也要使用会话API,例如this answer

答案 1 :(得分:0)

您可以尝试使用pg_typeof函数,该函数返回文本字符串,并使用CASE语句强制进行比较(否则,不能保证postgres会短路OR​​ in正确的顺序)。然后,您可以先转换为文本,然后再返回时间戳,以强制进行正确的转换,这虽然不大,但应该有效。

SELECT *
FROM sample AS s
WHERE s.isActive
  AND 
    CASE WHEN pg_typeof( :createdAfter ) = 'bytea' THEN TRUE
       WHEN s.insert_time > ( ( :createdAfter )::text)::timestamp THEN TRUE
       ELSE FALSE 
    END