繁体   English   中英

当postgresql中的“没有时区的时间戳”时,Java中的参数类型应该是什么?

[英]What should the type of parameter be in Java when it is a “timestamp without time zone” in postgresql?

我正在尝试通过 Java 和 JDBC 在 postgresql 中运行查询。

postgresql中“table”的“activitydate”列是“timestamp without time zone”。 我尝试使用 String 传递日期但没有用( org.postgresql.util.PSQLException: ERROR: operator does not exist: timestamp without time zone > character changed)

我应该使用什么类型而不是String来存储“start_date”和“end_date”并将它们传递给查询?

BTW SELECT COUNT(*) FROM table WHERE activitydate > '2014-11-20' AND activitydate < '2014-11-21' AND zipcode = 12345在 pgadmin 中完美运行。

public Response query(
          @QueryParam("start_date") String start_date,
          @QueryParam("end_date") String end_date,
          @QueryParam("zipcode") String zipcode
          ) throws Exception {
...
...

pstmt = conn.prepareStatement("SELECT COUNT(*) FROM table WHERE activitydate > ? AND activitydate < ? AND zipcode = ?");

pstmt.setString(1, start_date); 
pstmt.setString(2, end_date); 
pstmt.setString(3, zipcode); 

更新:我将其更改为 java.sql.Timestamp 但仍然不起作用:

public Response query(
          @QueryParam("start_date") Timestamp start_date,
          @QueryParam("end_date") Timestamp end_date,
          @QueryParam("zipcode") String zipcode
          ) throws Exception {
...
...

pstmt = conn.prepareStatement("SELECT COUNT(*) FROM table WHERE activitydate > ? AND activitydate < ? AND zipcode = ?");

pstmt.setTimestamp(1, start_date); 
pstmt.setTimestamp(2, end_date); 
pstmt.setString(3, zipcode);

tl;博士

对于使用半开放时间跨度的 SQL:
"SELECT * FROM tbl WHERE when !< ? AND when < ? ; "

myPreparedStatement.setObject(       // Use a prepared statement so you can pass smart objects rather than dumb strings.
    1 ,                              // Specify which placeholder is being fulfilled.
    LocalDate                        // Represent a date-only value, without time-of-day and without time zone or offset-from-UTC.
    .parse( "2014-11-20" )           // Parse an input string in standard ISO 8601 format to get a `LocalDate` object.
    .atStartOfDay()                  // Determine the first moment of the day on that date. Returns a `LocalDateTime` object representing a date with time-of-day but lacking any concept of time zone or offset-from-UTC.
) ;
myPreparedStatement.setObject( 
    2 , 
    LocalDate
    .parse( "2014-11-21" )
    .atStartOfDay()
) ;

当心:我猜您在数据库中为您的列使用了错误的类型。 时刻只能使用TIMESTAMP WITH TIME ZONE进行跟踪而不能使用TIMESTAMP WITHOUT TIME ZONE进行跟踪 搜索堆栈溢出以获取更多信息。

不是片刻

Jens 的答案现在已经过时了。 现在你应该使用现代的java.time类来取代麻烦的旧的遗留日期时间类。

postgresql中的“没有时区的时间戳”?

Postgres 和 SQL 标准上的这种数据类型都故意缺少从 UTC 或时区偏移的上下文。 所以,请注意,这种类型不能代表一个时刻,不是时间线上的一个点。

我把它改成了 java.sql.Timestamp

不,错误的数据类型。 java.sql.Timestamp类除了是遗留的并且在设计上存在严重缺陷之外,还代表一个时刻,时间轴上的一个特定点。 所以这与您的TIMESTAMP WITHOUT TIME ZONE类型的列不匹配。

LocalDateTime

您应该改为使用LocalDateTime类。 此类表示具有时间的日期,但缺少任何偏移量或时区的概念。

从数据库中检索值。

LocalDateTime ldt = myResultSet.getObject( … , LocalDateTime.class ) ;

将值发送到数据库。

myPreparedStatement.setObject( … , ldt ) ;

一天的开始

SELECT COUNT(*) FROM table WHERE activitydate > '2014-11-20' AND activitydate < '2014-11-21'

你这里有另一个不匹配。 您提供的是仅限日期的值,但您的列包含日期时间值。

另一个问题:您在应该使用智能对象的地方使用了哑字符串。 从 JDBC 4.2 开始,我们可以与数据库交换java.time对象。 使用带有占位符的PreparedStatement ,并通过`set 传递对象

Java(旧版和现代版)和标准 SQL 中的日期时间类型表

为了解决带时间的日期问题,我们需要确定一天的开始。 使用LocalDateTime ,我们无需考虑时区异常。 所以一天总是从 00:00 开始。 尽管如此,我们应该养成询问java.time来确定一天开始的习惯。

LocalDate startDate = LocalDate.parse( "2014-11-20" ) ;
LocalDate stopDate = LocalDate.parse( "2014-11-21" ) ;

LocalDateTime start = startDate.atStartOfDay() ;
LocalDateTime stop = stopDate.atStartOfDay() ;

用占位符为您编写 SQL。

我建议你改变你的想法,养成使用半开放方法来定义时间跨度的习惯。 在半开中,开头是包容的,而结尾是独占的 因此,对于 20 日的整个一天,搜索等于或晚于 20 日的日期,并运行到(但包括)21 日。 至于第一部分,“等于或以后”的更简短的说法是“不在之前”,因此我们使用!<

String sql = "SELECT * FROM tbl WHERE when !< ? AND when < ? ; " ;

将该sql字符串提供给您准备好的语句。 然后为占位符传递两个LocalDateTime对象。

myPreparedStatement.setObject( 1 , start ) ;
myPreparedStatement.setObject( 2 , stop ) ;

您必须使用java.sql.Timestampjava.sql.Date

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM