2013-03-13 37 views
4

我有以下幾點:(使用IPython中)cx_Oracle「ORA-01843:不是有效的一個月使用Unicode參數

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 [email protected]>> 

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 [email protected]>> 

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 [email protected]>> 

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]),更奇怪的是,在我這樣做之後,我需要在重新使用普通字符串之前重置會話NLS格式。

我使用: Cx_Oracle 5.1.2 蟒蛇2.7.3 甲骨文10.2.0.1.0

任何想法?

謝謝您的閱讀時間。

回答

5

它實際上是在Oracle 10.5.0.2和11.2.0.1的錯誤。

錯誤可被再現爲以下:在會話

集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; 
1

我無法使用RHEL 5重新創建錯誤,Cx_Oracle 5.1 python 2.4.3 Oracle 11.2.0.3.0 您是否嘗試使用帶有to_date和to_timestamp函數的格式化字符串?

https://gist.github.com/fclrc/5435561

#! /bin/python 
import cx_Oracle 
import platform 

print ("Python version: " + platform.python_version()) 
print ("cx_Oracle version: " + cx_Oracle.version) 
print ("Oracle client: " + str(cx_Oracle.clientversion()).replace(', ','.')) 

connection = cx_Oracle.connect('user/[email protected]') 
cursor = connection.cursor() 
# 
# Option with format strings 
# 
cursor.execute("""select to_date(:arg1,'yyyy-mm-dd'), to_timestamp(:arg2,'yyyy-mm-dd hh24.mi.ss.ff') from dual""", arg1=u'2013-03-12', arg2=u'2013-03-12 08:22:31.332144') 
# 
# Option without format strings 
# 
#cursor.execute("ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS' NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH24:MI:SS.FF'") 
#cursor.execute("select to_date(:0), to_timestamp(:1) from dual", [u'2013-03-12', u'2013-03-12 08:22:31.332144']) 

mydate = cursor.fetchall() 
print mydate 
cursor.close() 
connection.close() 
+0

它使用的格式字符串工作正常,問題是,SQL代碼Django在保存模型時產生的,我想避免手動做插入。感謝你的回答。 – Magarato 2013-04-30 21:00:40

0

基於jtiai問題description,我提出以下解決方法 - 調用任何有問題的SQL-S(如Oracle 10.5.0.2和11.2.0.1,cx_oracle 5.1之前0.2),再次復位NLS_DATE_FORMAT/NLS_TIMESTAMP_FORMAT:

cursor.execute(
    "ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS'" 
    " NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH24:MI:SS.FF'") 

# do execute ... 
cursor.execute(query, params) 
相關問題