Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/398.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Java中,参数的类型应该是什么;不带时区的时间戳“;在postgresql中?_Java_Postgresql_Jdbc - Fatal编程技术网

在Java中,参数的类型应该是什么;不带时区的时间戳“;在postgresql中?

在Java中,参数的类型应该是什么;不带时区的时间戳“;在postgresql中?,java,postgresql,jdbc,Java,Postgresql,Jdbc,我试图通过Java和JDBC在postgresql中运行一个查询 postgresql中“表”的“activitydate”列是“没有时区的时间戳”。我试图使用字符串传递日期,但没有成功(org.postgresql.util.psqleexception:错误:运算符不存在:时间戳不带时区>字符变化) 我应该使用什么类型而不是字符串来存储“开始日期”和“结束日期”并将它们传递给查询 顺便说一句,从表中选择计数(*),其中activitydate>'2014-11-20'和activitydat

我试图通过Java和JDBC在postgresql中运行一个查询

postgresql中“表”的“activitydate”列是“没有时区的时间戳”。我试图使用字符串传递日期,但没有成功(org.postgresql.util.psqleexception:错误:运算符不存在:时间戳不带时区>字符变化)

我应该使用什么类型而不是字符串来存储“开始日期”和“结束日期”并将它们传递给查询

顺便说一句,从表中选择计数(*),其中activitydate>'2014-11-20'和activitydate<'2014-11-21'以及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); 
公共响应查询(
@QueryParam(“开始日期”)字符串开始日期,
@QueryParam(“结束日期”)字符串结束日期,
@QueryParam(“zipcode”)字符串zipcode
)抛出异常{
...
...
pstmt=conn.prepareStatement(“从表中选择计数(*),其中activitydate>和activitydate<?和zipcode=?”;
pstmt.setString(1,开始日期);
pstmt设置管柱(2,结束日期);
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);
公共响应查询(
@QueryParam(“开始日期”)时间戳开始日期,
@QueryParam(“结束日期”)时间戳结束日期,
@QueryParam(“zipcode”)字符串zipcode
)抛出异常{
...
...
pstmt=conn.prepareStatement(“从表中选择计数(*),其中activitydate>和activitydate<?和zipcode=?”;
pstmt.setTimestamp(1,开始日期);
pstmt.setTimestamp(2,结束日期);
pstmt.setString(3,zipcode);

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

tl;dr 对于使用半开放时间跨度的SQL:
“从tbl WHERE when!<?和when<?;”选择*

注意:我猜您在数据库中使用了错误的列类型。只能使用带时区的
时间戳来跟踪时间,而不能使用不带时区的
时间戳来跟踪时间。有关详细信息,请搜索堆栈溢出

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

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

Postgres和SQL标准上的此数据类型故意缺少UTC偏移量或时区的上下文。因此,请注意,此类型不能代表一个时刻,也不是时间线上的一个点

我把它改为java.sql.Timestamp

不,错误的数据类型。
java.sql.Timestamp
类除了是遗留的,而且在设计上存在严重缺陷之外,还代表了一个时刻,时间轴上的一个特定点。因此,这与没有时区的
Timestamp类型的列不匹配

LocalDateTime
您应该改为使用
LocalDateTime
类。该类表示一天中某个时间的日期,但没有任何偏移量或时区的概念

从数据库中检索值

LocalDateTime ldt = myResultSet.getObject( … , LocalDateTime.class ) ;
myPreparedStatement.setObject( … , ldt ) ;
将值发送到数据库

LocalDateTime ldt = myResultSet.getObject( … , LocalDateTime.class ) ;
myPreparedStatement.setObject( … , ldt ) ;
一天的开始 从activitydate>'2014-11-20'和activitydate<'2014-11-21'的表格中选择计数(*)

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

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

要解决date with time of day的问题,我们需要确定一天的开始时间。使用
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日,但不包括21日。对于第一部分,短时间表示“等于或更高”的方法是“不在之前”,所以我们使用
!不要使用字符串作为时间戳。创建
java.sql.Timestamp
的实例,并使用
setTimestamp()
传递它。您介意详细说明一下吗?我改为“@QueryParam(“start_date”)Timestamp start_date,@QueryParam(“end_date”)Timestamp end_date”+“pstmt.setTimestamp(1,开始日期);pstmt.setTimestamp(2,结束日期);”但仍然不起作用。从JDBC 4.2开始,使用java.time对象进行此类工作。
java.sql.date
是个坏主意,因为它删除了时间部分(或者更准确地说:将时间设置为
00:00
)@问题中没有名字的马看起来OP没有时间段,所以
java.sql.Date
对我来说没问题。你介意详细说明一下吗?我改为“@QueryParam(“开始日期”)时间戳开始日期,@QueryParam(“结束日期”)时间戳结束日期”+”pstmt.setTimestamp(1,开始日期);pstmt.setTimestamp(2,结束日期);“但仍然不起作用。什么意思是
但仍然不起作用
相同的错误消息?只有空白页。我使用“./query?开始日期=2014-11-20&结束日期=2014-11-21&zipcode=92093”
myPreparedStatement.setObject( 1 , start ) ;
myPreparedStatement.setObject( 2 , stop ) ;