python - cx_Oracle 'ORA-01843: not a valid month' 带有 unicode 参数

标签 python oracle unicode cx-oracle

我有以下内容:(使用 ipython)

In [30]: con = cx_Oracle.connect('refill_test02/******@MYDB')

In [31]: cur = con.cursor()

In [32]: cur.execute("ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS' NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH24:MI:SS.FF'")

In [33]: cur.execute("select to_date(:0), to_timestamp(:1) from dual", ['2013-03-12', '2013-03-12 08:22:31.332144'])
Out[33]: <__builtin__.OracleCursor on <cx_Oracle.Connection to refill_test02@MYDB>>

In [34]: cur.fetchall()
Out[34]: 
[(datetime.datetime(2013, 3, 12, 0, 0),
  datetime.datetime(2013, 3, 12, 8, 22, 31, 332144))]

In [35]: cur.execute("select to_date(:0), to_timestamp(:1) from dual", [u'2013-03-12', '2013-03-12 08:22:31.332144'])
Out[35]: <__builtin__.OracleCursor on <cx_Oracle.Connection to refill_test02@MYDB>>

In [36]: cur.fetchall()
Out[36]: 
[(datetime.datetime(2013, 3, 12, 0, 0),
  datetime.datetime(2013, 3, 12, 8, 22, 31, 332144))]

In [37]: cur.execute("select to_date(:0), to_timestamp(:1) from dual", [u'2013-03-12', u'2013-03-12 08:22:31.332144'])
---------------------------------------------------------------------------
DatabaseError                             Traceback (most recent call last)
/home/xxxxx/<ipython-input-37-8af80e5fc40c> in <module>()
----> 1 cur.execute("select to_date(:0), to_timestamp(:1) from dual", [u'2013-03-12', u'2013-03-12 08:22:31.332144'])

DatabaseError: ORA-01843: not a valid month


In [38]: cur.execute("select to_date(:0), to_timestamp(:1) from dual", [u'2013-03-12', '2013-03-12 08:22:31.332144'])
---------------------------------------------------------------------------
DatabaseError                             Traceback (most recent call last)
/home/xxxx/<ipython-input-38-bc628f006aa3> in <module>()
----> 1 cur.execute("select to_date(:0), to_timestamp(:1) from dual", [u'2013-03-12', '2013-03-12 08:22:31.332144'])

DatabaseError: ORA-01843: not a valid month


In [39]: cur.execute("ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS' NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH24:MI:SS.FF'")

In [40]: cur.execute("select to_date(:0), to_timestamp(:1) from dual", [u'2013-03-12', '2013-03-12 08:22:31.332144'])
Out[40]: <__builtin__.OracleCursor on <cx_Oracle.Connection to refill_test02@MYDB>>

In [41]: cur.fetchall()
Out[41]: 
[(datetime.datetime(2013, 3, 12, 0, 0),
  datetime.datetime(2013, 3, 12, 8, 22, 31, 332144))]

出于某种原因,我不能将 unicode 字符串用于时间戳参数 (IN[37]),更奇怪的是,在我这样做之后,我需要重置 session NLS 格式,然后才能再次使用普通字符串。

我正在使用: Cx_Oracle 5.1.2 python 2.7.3 甲骨文 10.2.0.1.0

有什么想法吗?

感谢您花时间阅读本文。

最佳答案

这实际上是 Oracle 10.5.0.2 和 11.2.0.1 中的一个错误。

错误可以重现如下:

在 session 中设置 NLS_TIMESTAMP_FORMAT。

使用 unicode 数据运行任何隐式或显式 TO_DATE 转换。

接下来带有 unicode 数据的隐式或显式 TO_TIMESTAMP 将触发时间戳格式的内部重置。

所有连续的 TO_TIMESTAMP 都将失败,时间戳的 TO_CHAR 将产生无效输出。

下面是测试行为的代码:

ALTER SESSION SET NLS_TERRITORY = 'AMERICA';
ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS' NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH24:MI:SS.FF';

REM --- WORKS:
SELECT TO_TIMESTAMP('2013-06-24 18:15:10.312') FROM DUAL;

REM --- WORKS:
SELECT TO_DATE('2013-06-24 18:15:10') FROM DUAL;

REM --- WORKS:
SELECT TO_TIMESTAMP('2013-06-24 18:15:10.312') FROM DUAL;

REM --- WORKS:
SELECT TO_TIMESTAMP(x) FROM (SELECT CAST('2013-06-24 18:15:10.312' AS NVARCHAR2(30)) AS X FROM DUAL);

REM --- WORKS:
SELECT TO_DATE(x) FROM (SELECT CAST('2013-06-24 18:15:10' AS NVARCHAR2(30)) AS X FROM DUAL);

REM --- WORKS:
SELECT TO_TIMESTAMP('2013-06-24 18:15:10.312') FROM DUAL;

REM !!! FAILS!
SELECT TO_TIMESTAMP(x) FROM (SELECT CAST('2013-06-24 18:15:10.312' AS NVARCHAR2(30)) AS X FROM DUAL);

REM !!! FAILS!
SELECT TO_TIMESTAMP('2013-06-24 18:15:10.312') FROM DUAL;

REM --- WORKS:
SELECT TO_DATE('2013-06-24 18:15:10') FROM DUAL;

关于python - cx_Oracle 'ORA-01843: not a valid month' 带有 unicode 参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15396241/

相关文章:

python - 优化分区函数

python - SQLAlchemy:两个日期之间的差异

sql - 使用 substr 和 instr 更新分隔字符串

c++ - 如果我不调用ReleaseStringUTFChars,它会在JNI调用结束时自动调用吗?

python - 在 Windows 10 上使用打开的 cv2 获取 USB 摄像头 ID

python - 将单个文件附加到电子邮件

sql - 在sql developer中执行异步存储过程

python - 修复由智能引号引起的 UnicodeEncodeError

C++字符串文字仍然令人困惑

python - 如何使用Python对字符串进行编码