Java:ResultSet getString()因环境而异

Java:ResultSet getString()因环境而异,java,sql,oracle,datetime,formatting,Java,Sql,Oracle,Datetime,Formatting,我有一个返回oracle日期对象的SQL查询。 e、 g: 从DUAL中选择sysdate 当前有代码执行以下操作: 字符串s=rs.getString(“sysdate”) 问题是,这会在不同的环境中返回不同的日期格式(数据库是相同的) 一个环境将返回: 2011-01-31 12:59:59.0 另一个将返回更奇怪的结果: 2011-1-31 12.15.32.0(时间以小数分隔) 也许这和语言环境有关。。。一台机器是java报告的“英语(加拿大)”,另一台是“英语(美国)” 我感兴趣的是,

我有一个返回oracle日期对象的SQL查询。 e、 g:

从DUAL中选择sysdate

当前有代码执行以下操作:

字符串s=rs.getString(“sysdate”)

问题是,这会在不同的环境中返回不同的日期格式(数据库是相同的)

一个环境将返回:
2011-01-31 12:59:59.0

另一个将返回更奇怪的结果:
2011-1-31 12.15.32.0
(时间以小数分隔)

也许这和语言环境有关。。。一台机器是java报告的“英语(加拿大)”,另一台是“英语(美国)”


我感兴趣的是,当结果集将日期对象转换为字符串时,该格式来自何处?

不要使用
getString
,使用
getDate
(或
getTimestamp
)。这样,它就不会依赖数据库引擎将其转换为字符串。

我建议根本不要调用
getString
。您请求的值不是字符串,而是日期或时间戳。因此,请调用
getDate
getTimestamp
。(我不知道哪一个最合适;这取决于
sysdate
的确切语义)

如果您需要格式化它,您可以以适当的方式进行格式化


基本上,代码和数据库之间的文本转换越少越好。这是使用参数化查询的一个原因——您不必关心数据库将如何解析数值或日期和时间;你只是提供了价值。这是同样的事情,但恰恰相反。

如果您真的想将其作为字符串,最好在查询中使用to_char

SELECT to_char(sysdate, 'MM/DD/YYYY') FROM DUAL; 
这将是一致的。

来自Oracle网站:

在数据库连接时,JDBC 类库设置服务器 NLS_语言和NLS_领土 与区域设置相对应的参数 运行JDBC的Java虚拟机的 司机


是的,响应的不同是因为机器指定了不同的区域设置。正确的解决方案应该是使用getDate()或getTimestamp(),或者让数据库服务器以前面提到的特定格式以字符串形式返回日期。

在11g驱动程序中,该格式似乎是硬编码的。对结果集调用
getString()
,最终会调用以下内容:

oracle.sql.TIMESTAMPTZ.toString(int year, int month, int day, int hours, int minutes, int seconds, int nanos, String regionName)
对于日期,
oracle.jdbc.driver.DateAccessor.getString()
使用nanos=-1调用此函数,结果使用格式“yyyy-mm-dd HH:mm:SS”

对于时间戳,格式为“yyyy-mm-dd HH:mm:SS.S”。最多包括9位纳秒

实际上,另一个有趣的结果是,从10g到11g有了显著的变化:

10.2.0.5.0

select a DATE value and use getString to read it

2009-04-20 00:00:00.0

select a TIMESTAMP value and use getString to read it

2010-10-15.10.16. 16. 709928000
select a DATE value and use getString to read it

2009-04-20 00:00:00

select a TIMESTAMP value and use getString to read it

2010-10-15 10:16:16.709928
11.2.0.2.0

select a DATE value and use getString to read it

2009-04-20 00:00:00.0

select a TIMESTAMP value and use getString to read it

2010-10-15.10.16. 16. 709928000
select a DATE value and use getString to read it

2009-04-20 00:00:00

select a TIMESTAMP value and use getString to read it

2010-10-15 10:16:16.709928

您的环境是否会使用不同版本的Oracle JDBC驱动程序?

事实上,日期上的getString绝对不是理想的解决方案。我仍然对理解getString的格式来源感兴趣。现在,我使用resultset元数据来检查我从哪种类型的列中提取数据。(该代码预计将处理可能有不同列的结果集)@Will:即使是Rich的答案在我看来也不是确定的。不清楚到底是数据库执行转换,还是
ResultSet
code。如果是后者,那么NLS_语言和NLS_领土当然是不相关的。我的猜测是后者——基本上,
getString()
正在有效地调用
getObject(column).toString()
。Jon是对的。Oracle端不会执行数据类型转换,因为查询以日期格式返回日期(尽管Oracle在int-date格式中包含时间,所以它实际上是日期时间)。对字符串的转换发生在客户端。@Gary从JDBC驱动程序10.2.0.4.0开始,转换是由驱动程序本身在
DateAccessor\getString
方法中执行的(硬编码转换)。从技术上讲,是会话的
NLS\U DATE\U格式
控制Oracle将日期隐式转换为字符串的方式(或日期字符串)在没有显式格式字符串的情况下。如果未显式指定日期格式,
NLS\U date\U格式
是从
NLS\U区域
派生的。