Python cx_Oracle执行UPDATE遇ORA-00933命令未正确结束如何解决
问题原因
- 核心报错根因与SQL末尾的分号无关,是日期值的格式不符合Oracle语法要求:你当前应该是直接把Python datetime对象拼接进了SQL字符串,datetime转字符串后生成的
2020-02-03 12:14:28属于非法字面量,Oracle无法识别这种无标识的日期格式,解析时判定语法中断,因此抛出ORA-00933错误。 - Oracle原生支持的日期写法仅包含两类:一是带标识的字面量
DATE 'YYYY-MM-DD'(仅日期)、TIMESTAMP 'YYYY-MM-DD HH24:MI:SS'(带时间戳);二是用TO_DATE()/TO_TIMESTAMP()函数显式做格式转换,直接写无引号无标识的日期字符串会被判定为非法语法。
解决方法
方案1(生产环境推荐):使用cx_Oracle参数绑定传递datetime对象
不需要手动处理日期格式,同时避免SQL注入风险,是cx_Oracle官方推荐的写法:
import cx_Oracle import datetime # 数据库连接逻辑省略 conn = cx_Oracle.connect("用户名/密码@主机:端口/服务名") cursor = conn.cursor() # 待更新参数 row_name_val = 345434 issue_date_val = datetime.datetime(2020,2,3,12,14,28) row_id_val = 327692 # 编写带占位符的SQL update_sql = """ UPDATE TABLE_NAME SET ROW_NAME = :1, ISSUE_DATE = :2 WHERE ROW_ID = :3 """ # 执行时传入参数元组,cx_Oracle会自动处理datetime类型的适配 cursor.execute(update_sql, (row_name_val, issue_date_val, row_id_val)) conn.commit() # 资源关闭逻辑省略
方案2(仅测试场景使用):手动拼接时显式转换日期格式
如果必须手动拼接SQL,需要用TO_DATE函数做日期转换,注意字符串的引号转义:
issue_date_str = "2020-02-03 12:14:28" update_sql = f""" UPDATE TABLE_NAME SET ROW_NAME = 345434, ISSUE_DATE = TO_DATE('{issue_date_str}', 'YYYY-MM-DD HH24:MI:SS') WHERE ROW_ID = 327692 """
该方案存在SQL注入风险,禁止在生产环境使用。
内容的提问来源于stack exchange,提问作者Ajax
相关产品推荐
相关产品推荐

