为何同一Oracle查询在SQL Developer正常,Python cx_Oracle运行报错
cx_Oracle执行Oracle日期查询报ORA-01843无效月份的解决方案
问题根因
报错核心原因是Oracle客户端的NLS日期格式参数不一致:
TRUNC(SYSDATE,'HH') - interval '1' hour返回的是Oracle DATE类型,你直接传入to_timestamp指定格式时,Oracle会先把DATE类型隐式转换为字符串,再按你给出的格式模板转换为时间戳。- SQL Developer的会话默认
NLS_DATE_FORMAT参数和你通过cx_Oracle建立的会话参数不同,cx_Oracle会话隐式转换出的日期字符串和你写的mm-dd-yyyy hh24:mi:ss格式不匹配,所以抛出无效月份错误。
解决方案
方案1:删除to_timestamp的格式参数(最简洁)
DATE类型直接转时间戳不需要手动指定格式,直接修改查询语句即可:
select to_timestamp(TRUNC(SYSDATE,'HH') - interval '1' hour) from dual
方案2:显式控制格式转换(完全规避NLS参数影响)
先把DATE类型显式转为指定格式的字符串,再转时间戳,不会受客户端参数影响:
select to_timestamp( to_char(TRUNC(SYSDATE,'HH') - interval '1' hour, 'mm-dd-yyyy hh24:mi:ss'), 'mm-dd-yyyy hh24:mi:ss' ) from dual
方案3:统一cx_Oracle会话的NLS参数
建立连接后手动修改会话的日期格式,和SQL Developer保持一致:
# 建立连接后执行语句修改会话参数 conn = cx_Oracle.connect(user='testUser', password='user123', dsn=dsn_tns) cursor = conn.cursor() cursor.execute("ALTER SESSION SET NLS_DATE_FORMAT = 'MM-DD-YYYY HH24:MI:SS'") # 再执行你的查询即可
内容的提问来源于stack exchange,提问作者Aakash Basu
相关产品推荐
相关产品推荐

