【问题标题】:Cx_oracle is cutting year in a date field in some specific cases在某些特定情况下,Cx_oracle 会在日期字段中剪切年份
【发布时间】:2015-09-24 03:28:29
【问题描述】:

在使用 python 和 cx_Oracle 处理日期时,我遇到了下一个问题。

这个很好用:

In [29]: cursor.execute("SELECT TO_DATE('23.09.2015','DD.MM.YYYY') FROM dual")
Out[29]: <cx_Oracle.Cursor on <cx_Oracle.Connection to web@hdb:1521/db11>>

In [30]: cursor.fetchone()
Out[30]: (datetime.datetime(2015, 9, 23, 0, 0),)

这也很好用:

In [33]: cursor.execute("SELECT sysdate FROM dual")
Out[33]: <cx_Oracle.Cursor on <cx_Oracle.Connection to web@hdb:1521/db11>>

In [34]: cursor.fetchone()
Out[34]: (datetime.datetime(2015, 9, 23, 21, 25, 16),)

但是当我使用带有日期字段 cx_Oracle 的 oracle to_date 函数时,将年份值减少到 2 位,所以我得到的是 2015 而不是 15。此处示例:

In [31]: cursor.execute("SELECT TO_DATE(TO_DATE('23.09.2015','DD.MM.YYYY'),'DD.MM.YYYY') FROM dual")
Out[31]: <cx_Oracle.Cursor on <cx_Oracle.Connection to web@hdb:1521/db11>>

In [32]: cursor.fetchone()
Out[32]: (datetime.datetime(15, 9, 23, 0, 0),)

这里:

In [36]: cursor.execute("SELECT TO_DATE(sysdate,'DD.MM.YYYY') FROM dual")
Out[36]: <cx_Oracle.Cursor on <cx_Oracle.Connection to web@hdb:1521/db11>>

In [37]: cursor.fetchone()
Out[37]: (datetime.datetime(15, 9, 23, 0, 0),)

oracle 中还有一个trunc 函数,可用于日期舍入,不会引发问题:

In [39]: cursor.execute("SELECT TRUNC(sysdate) FROM dual")
Out[39]: <cx_Oracle.Cursor on <cx_Oracle.Connection to web@hdb:1521/db11>>

In [40]: cursor.fetchone()
Out[40]: (datetime.datetime(2015, 9, 23, 0, 0),)

但我想我的工具可以在没有任何特定限制的情况下使用用户定义的数据库对象(包括视图)。不幸的是,这个问题无法让我正确处理日期,目前我找不到任何合适的解决方案。

编辑。 Rajesh 回答后的工作示例:

In [104]: cursor.execute("ALTER SESSION SET NLS_DATE_FORMAT='DD.MM.YYYY'")

In [105]: cursor.execute("SELECT TO_DATE(sysdate,'DD.MM.YYYY') FROM dual")
Out[105]: <cx_Oracle.Cursor on <cx_Oracle.Connection to web@hdb:1521/db11>>

In [106]: cursor.fetchone()
Out[106]: (datetime.datetime(2015, 9, 23, 0, 0),)

【问题讨论】:

    标签: python cx-oracle


    【解决方案1】:

    这个问题的简单答案是不再在日期函数上使用 to_date。

    你的转换函数应该是

    a) to_date(string_column,'string_representation') 如果您尝试将某些内容转换为日期

    b) to_char(date_column,'string_representation') 如果您尝试将某些内容从日期转换为字符串,通常用于报告、假脱机或打印。

    如果您想了解奇怪的行为,可以查看会话的 NLS 设置。当您说 TO_DATE(sysdate,...) 时,to_date 需要一个字符串,所以我认为 Oracle 会尝试将 sysdate 隐式转换为字符串。在当前会话中使用 NLS_DATE_FORMAT 会发生这种情况。

    【讨论】:

    • 干杯!谢谢你的回答!我已将工作示例放在主帖中
    • 嗨,奥列格 - 我仍然不明白你为什么需要一个 to_date。在您的代码中,您的变量“a”定义为什么?
    • 从上一个示例中删除了变量“a”,因此它不会让任何人感到困惑,它意外地来自我的测试。我不需要to_date,因为我可以使用trunc 进行日期舍入,但我不能保证用户会避免它,而且我在他们之前遇到过这种行为很酷。实际上我一直在使用to_date 在 sql 视图中进行日期舍入,因为我从未怀疑过这样的方面
    • 好的。因此,正确的解决方案是使用 trunc(sysdate) 如果您想要日期输出或 to_char(sysdate,'string format') 如果您想要分配/返回字符串数据类型。无论哪种方式,都没有 to_date(sysdate) 的情况。希望这很清楚:)
    猜你喜欢
    • 2021-05-16
    • 2012-01-14
    • 2012-01-28
    • 1970-01-01
    • 2015-11-20
    • 2018-03-14
    • 1970-01-01
    • 1970-01-01
    • 2013-06-01
    相关资源
    最近更新 更多