Java 如果不为空,则比较日期
我需要找到createdate>X的所有记录。X是一个sql.Timestamp,可能为null,在这种情况下,我只想返回所有记录。所以我试着:(createdAfter是时间戳) 但我得到的只是Java 如果不为空,则比较日期,java,postgresql,Java,Postgresql,我需要找到createdate>X的所有记录。X是一个sql.Timestamp,可能为null,在这种情况下,我只想返回所有记录。所以我试着:(createdAfter是时间戳) 但我得到的只是 org.postgresql.util.PSQLException: ERROR: could not determine data type of parameter $1 但是,如果在检查任意int是否为null时执行相同的查询: SELECT * FROM trades WHERE (:s
org.postgresql.util.PSQLException: ERROR: could not determine data type of parameter $1
但是,如果在检查任意int是否为null时执行相同的查询:
SELECT *
FROM trades
WHERE (:sInt ISNULL OR trades.insert_time > :createdAfter )
然后它就起作用了。怎么了 如果您想坚持使用这样的本机查询,没有简单的解决方案。
null
值被转换为bytea
值。参见示例和
该值很难铸造或与时间戳
值进行比较
问题不在于第一次比较,而是通过使用coalesce来处理,如:
COALESCE(:createdAfter) ISNULL
因为在实际值和数据类型之间没有比较关系。但是比较
sometimestamp::timestamp>null::bytea
(强制转换只是为了显示实际的类型,因此不起作用)
在过程和异常处理之后可能需要更多的逻辑,不确定
因此,如果JPQL或CriteriaQueries不可能,您只有不好的选项:
- 通过字符串连接或其他方式设置参数来构造查询(不!也不确定realy是否有效)
- 使用
查询,更多代码和工作PreparedStatement
- 如果使用Hibernate,也可以使用会话api,如
pg_typeof
函数,并使用CASE
语句强制进行比较(否则无法保证postgres将以正确的顺序短路OR)。然后,您可以通过转换为文本,然后再转换回时间戳来强制进行正确的转换,这虽然不雅观,但应该是有效的
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
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