我正在尝试使用JDBC调用PL / SQL过程(使用下面提到的签名)。它采用TIMESTAMP WITH LOCAL TIME ZONE
类型的参数。我使用的是Oracle 11g
和Oracle 12c Jdbc Driver Version 12.1.0.2
。
-- PURPOSE: Takes a timestamp and returns the formatted string
PROCEDURE deal_With_TimeStamp(intime TIMESTAMP WITH LOCAL TIME ZONE , outTimeString OUT VARCHAR2)
我编写了一个使用JDBC调用上述过程的Java方法。我最终希望在Web服务中公开此方法。
我试图了解在这种情况下如何处理TIMESTAMP WITH LOCAL TIME ZONE
类型的参数。
根据我的阅读,似乎TIMESTAMP WITH LOCAL TIME ZONE
将根据数据库实例运行的时区对所有时间戳进行规范化。一旦将其考虑在内,它将丢弃客户端时区信息(如果提供)用于规范化过程。因此,如果客户端请求此信息,他们将不得不再次传递他们的时区信息以及请求。
在这种情况下,我是否应该接受来自Web服务客户端的时间戳和时区?这样,存储在数据库中的信息将是准确的。
没有时区信息发送时会发生什么?有没有办法为Jdbc连接设置时区?如果没有客户端的时区信息,可以将其传递给数据库。
以下是我使用JDBC的Java方法的相关部分。
public void dealWithTimeStamp(Timestamp currentTimestampValue , String clientTimeZone)
{
Connection conn = null;
CallableStatement callStmt = null;
// Create a Database connection
conn = DriverManager.getConnection(DB_URL , DB_USER , DB_PWD);
// Create a query string
String callProc = "{call HR.EMP_PKG.deal_With_TimeStamp ( ? , ?) }";
// Create a Callable statement
callStmt = conn.prepareCall(callProc);
// Bind values to the IN parameter
callStmt.setTimestamp(1, currentTimestampValue , Calendar.getInstance(TimeZone.getTimeZone(clientTimeZone)));
// Register OUT parameters
callStmt.registerOutParameter(2, java.sql.Types.VARCHAR);
// Execute the Callable Statement
callStmt.execute();
// Retrieve the values from the OUT parameter
String curTimestampStr = callStmt.getString(2);
System.out.println("Current Timestamp : " + curTimestampStr);
}
请注意我已经对try catch块进行了条带化,为了便于阅读而清理了数据库资源 :
答案 0 :(得分:1)
根据我的阅读,似乎TIMESTAMP WITH LOCAL TIME ZONE将根据数据库实例运行的时区对所有时间戳进行规范化。一旦规范化完成,它将丢弃客户端时区信息(提供时)。
是,the docs指定此数据类型仅包含时间戳本身,而不包含时区字段。它与TIMESTAMP
的不同之处在于,传入值从客户端会话时区转换为数据库时区,传出值从另一个方向转换。
因此,如果客户请求此信息,他们将不得不再次传递他们的时区信息。
这取决于你所说的“客户”。 Web服务主机是数据库的客户端。它的时区是数据库会话的属性,因此您根本不必显式“传递”它。
但是,如果您指的是Web服务客户端,并且如果Web服务客户端需要提交和接收相对于其本地时区的时间戳(必须将其解释为此类型),则Web服务必须在其客户端之间转换时间戳。区域及其自己的区域,其中相应的Oracle数据类型为TIMESTAMP WITH LOCAL TIME ZONE
。为此,Web服务客户端必须为Web服务提供时区。
根据Web服务客户端的特性修改数据库连接的会话属性我会感到很不舒服。这似乎容易出错。如果您必须处理时区问题,那么我建议您通过标准化时区来解决问题:
ALTER SESSION
语句),每个连接一次,或者可以用Java进行半自动来实现。TIMESTAMP
,这应理解为以UTC表示。那么你根本不需要担心时区(与之前的结合)。 JDBC中没有标准的连接时区,但连接确实具有通用的“客户端属性”。 Oracle驱动程序可能会将会话时区公开为此类属性,在这种情况下,您可以通过Connection.setClientProperties()
进行设置。同样,我个人会基于Web服务客户端数据避免这样做,但我可以基于Web服务主机做这件事。