【问题标题】:NLS_DATE_FORMAT with JDBCNLS_DATE_FORMAT 与 JDBC
【发布时间】:2016-08-07 13:15:21
【问题描述】:

我尝试在 jdbc 中设置 NLS_DATE_FORMAT,它似乎没有任何效果。 我的代码:

//...
Connection conn = ods.getConnection();
Statement stat = conn.createStatement();

stat.execute("alter session set NLS_DATE_FORMAT='YYYY-DD-MM'");
ResultSet rs = stat.executeQuery("select date_column from test_table");

System.out.println(rs.getString(1));   // *** new format not effective here ***
//...
    

经过一番阅读。我知道 NLS_DATE_FORMAT 在 JDBC 驱动程序中是硬编码的。它是否正确 ?由此得出的结论:

语言和地域

Thin 驱动程序从 JVM user.language 属性中的 Java 语言环境获取语言和区域设置(NLS_LANGUAGE 和 NLS_TERRITORY)。日期格式(NLS_DATE_FORMAT)根据地域设置设置。

所以我尝试了这个:

Locale.setDefault(new Locale("en", "US"));
Connection conn = ods.getConnection();
Statement stat = conn.createStatement();

ResultSet rs = stat.executeQuery("select date_column from test_table");

System.out.println(rs.getString(1));   // *** JVM format not effective here 

但它不起作用。而不是得到类似的东西

10-OCT-15 (NLS_DATE_FORMAT for US = 'DD-MON-RR')

我明白了

2015-10-10 00:00:00.0

使用ORACLE 11g,Oracle jdbc驱动12.1,java 8

【问题讨论】:

  • ResultSet.getString()DATE 列上永远不会遵守 DBMS 特定的“NLS 设置”。它只是在从数据库中获取的日期值上调用java.sql.Timestamp.toString()。但是一开始就依赖任何隐式数据类型转换是一个坏主意。使用getTimestamp()SimpleDateFormat 在Java 代码中应用您想要的格式,或者在SELECT 语句中使用to_char() 让Oracle 对其进行格式化。
  • @a_horse_with_no_name 我想相信 toString() 被调用了。但是在检查 Data.toString 的文档时:以日期转义格式 yyyy-mm-dd 格式化日期。这不是我得到的格式吗?你怎么看 ?谢谢
  • java.sql.Date.toString() 返回该格式 - 它是内置的。您可以自己尝试System.out.pringln(new java.sql.Date(0).toString())java.sql.Timestamp 也是如此
  • FWIW,我唯一能找到引用文档的地方是 Oracle 8i 的文档。您需要在文档搜索中包含“11g”。 :)

标签: java oracle date jdbc


【解决方案1】:

JDBC 驱动程序的 NLS 支持为 dropped in Oracle 10g。无论如何,我建议您不要依赖特定于 Oracle 的 NLS 功能来格式化您的日期。

要格式化从 Java 中任何数据库检索的日期,请执行以下操作:

Connection conn = ods.getConnection();
Statement stat = conn.createStatement();

ResultSet rs = stat.executeQuery("select date_column from test_table");

DateFormat format = new SimpleDateFormat('yyyy-dd-MM');
System.out.println(format.format(rs.getDate(1));

请注意,SimpleDateFormat 的实例是可重用但不是线程安全的

如果您使用的是 Java 8,您可能希望改用新的和改进的 Java Time API。不幸的是,尚未更新 ResultSet 以返回 DateTime 的实例,因此您必须进行转换。查看DateTimeFormatterthis question 了解如何从旧版本转换为新版本。除其他优点外,DateTimeFormatter 是完全线程安全的。

新旧样式的格式模式相同; here are the docs 新的。

【讨论】:

  • 兼容的 JDBC 4.2 驱动程序需要通过getObject(int, Class<T>) 和相关方法支持java.time API。所以ResultSet.getObject(1, LocalDate.class) 需要工作。决定不再使用 getLocalDate 等方法进一步扩展 API。
  • @JakeRobb 我知道这一切。但是我不允许使用 getDate()。我需要将所有数据作为字符串检索。我进行了一些新的测试。实际上: stat.executeQuery("INSERT INTO tesy_table values ("10-OCT-15") 工作得很好。这意味着 JDBC 依赖于 JVM NLS_DATE_FORMAT。但我不知道为什么它不适用于 SELECT。
  • @iman: "我需要以字符串形式检索我的所有数据" - 没有冒犯,但这很愚蠢。
  • 我很想知道您为什么需要将所有数据作为字符串检索。这是什么,学校作业?也就是说,您可以使用不同的 SimpleDateFormat(使用与 10-OCT-15 格式匹配的模式)将字符串解析为日期,然后使用另一个 SDF 以您想要的方式对其进行格式化。
猜你喜欢
  • 2010-10-01
  • 2017-02-22
  • 1970-01-01
  • 2020-05-23
  • 1970-01-01
  • 2021-10-25
  • 1970-01-01
  • 1970-01-01
  • 2014-12-02
相关资源
最近更新 更多