【问题标题】:Java JDBC Procedure CallJava JDBC 过程调用
【发布时间】:2011-05-21 12:04:08
【问题描述】:

我有一个将日期作为参数并被两个不同的 Java Web 应用程序调用的 oracle 过程,在该过程中,我使用 to_char(date, 'd') 从传递的日期中提取日期。我无法找出为什么一个应用程序返回的日期与其他应用程序不同。我为这两个应用程序使用相同的 ojdbc 驱动程序。它与这些应用程序运行的机器环境变量有什么关系吗?

谢谢

【问题讨论】:

  • 我认为您的意思是 to_char(date, 'd') 而不是 sysdate(date, 'd')
  • 你能把程序的相关部分贴出来吗?
  • 谢谢亚当,你是对的。基本上我确实是这样做的 to_char(date, 'd') 就是这样。
  • 您能否添加一些您传入的日期和返回值的示例?
  • 哟,阿比迪。文森特回答了你的答案。我认为您应该将他的答案标记为确定的答案。

标签: java oracle jdbc call procedure


【解决方案1】:

尝试在两个应用程序中检查 JAVA/Oracle 中的默认语言环境。

我认为这可能取决于 JAVA 中设置的默认语言环境。

【讨论】:

  • 在我的网络应用程序中,我没有明确设置语言环境。 Oracle 中的默认值是 American。
【解决方案2】:

尝试通过在启动它们时向两个 webapp 容器传递 -Duser.timezone="America/New_York" VM 参数(根据您的时区需要调整)来明确指定它们的时区。

为了解决您的评论,在应用程序级别,您可以在调用存储过程时明确指定所需的时区。例如:

CallableStatement statement = null;
Connection conn = null;

    try {
        conn = getYourConnection();
        Calendar dbCal = new GregorianCalendar(YOUR_DATABASE_TIMEZONE);

        String sql = "begin schema_name.package_name.stored_proc(var1=>?, " +
                "var2=>?); end;";

        statement = conn.prepareCall(sql);
        statement.setInt(1, something);
        statement.setTimestamp(2, yourDate.getTime(), dbCal);

        statement.execute();

        conn.commit();

    } finally {
        if (statement!=null) statement.close();
        if (conn!=null) conn.close();
    }

【讨论】:

  • 我发现两台机器上的区域设置不同,其中一台机器完全设置了 LANGUAGE,而两台机器都将 LANG 设置为 LANG=en_GB.UTF-8。 @Dimitrisli 我认为这可以完成这项工作,但无论如何可以在上下文级别而不是在 tomcat 级别更改它。我的意思是如果我可以通过 context.xml (或其他东西)设置它只是为了一个应用程序?
  • @Abidi 您可以在 jdbc 调用存储过程期间指定您希望将日期保存在数据库中的时区,我已经用一个示例编辑了评论。
  • 感谢 Dimitrisli,我仍然不明白为什么相同的 Java 代码在两个不同的 web 应用程序中运行,两个 tomcat 使用相同的 JVM 参数会使 Oracle 计算不同日期的天数。
  • 我建议首先确定这种不一致的确切来源。调试您的两个应用程序并检查到达存储过程之前的日期,以查看它们是否不同。如果它们是,那么差异来自某个地方的应用程序,因此从一开始就更仔细地调试两者,以查看日期的确切差异。
【解决方案3】:

这是因为一周的第一天在所有国家/地区都不相同,例如在欧洲,一周的第一天是星期一,而在美国是星期日。考虑:

SQL> select * from nls_session_parameters where parameter = 'NLS_TERRITORY';

PARAMETER                      VALUE
------------------------------ ----------------------------------------
NLS_TERRITORY                  AMERICA

SQL> select to_char(date '2010-12-07', 'D') from dual;

TO_CHAR(DATE'2010-12-07','D')
-----------------------------
3

SQL> alter session set nls_territory=FRANCE;

Session altered

SQL> select to_char(date '2010-12-07', 'D') from dual;

TO_CHAR(DATE'2010-12-07','D')
-----------------------------
2

如果依赖它,则在过程开始时设置会话参数 NLS_TERRITORY。

【讨论】:

  • 没错,我同意,但是这两个应用程序都在访问相同的数据库、架构和过程,而且几天的结果是不同的。
  • @abidi:这是一个会话参数:它是由客户端设置的,而不是数据库。
猜你喜欢
  • 1970-01-01
  • 2015-05-28
  • 2016-05-03
  • 1970-01-01
  • 1970-01-01
  • 2013-07-25
  • 1970-01-01
  • 2015-04-20
  • 2018-09-13
相关资源
最近更新 更多