使用Pandas DataFrame通过Cx_Oracle更新Oracle表报ORA-01036错误如何解决
错误原因
执行报错:DatabaseError: ORA-01036: illegal variable name/number
- 你在SQL中使用了命名绑定变量(
:d、:c、:a、:b),但df.itertuples(index=False, name=None)生成的是无属性名的元组列表,cx_Oracle无法将元组的值和命名变量一一匹配 - 原始DataFrame包含5列(a、b、c、d、e),你传入的参数每个元组有5个值,但SQL仅需要4个绑定变量,参数数量不匹配
- 即使去掉多余列,元组的默认顺序(a、b、c、d)和SQL中绑定变量的顺序(d、c、a、b)也完全不对应,依然会触发报错
解决方法
提供两种可直接运行的修复方案:
方案1:使用命名绑定(推荐,无需关注参数顺序)
直接将需要的字段转换为字典列表,字典的key和SQL中的绑定变量名一一对应即可:
import pandas as pd import cx_Oracle d = {'a': ['first', 'second'], 'b': [3, 4], 'c': ['2021-01-01', '2021-01-02'], 'd':[1.1,2.2], 'e':[5,6] } df = pd.DataFrame(data=d) # 只提取SQL需要的4列,转换为字典列表 data = df[['a','b','c','d']].to_dict('records') DBCONN = cx_Oracle.connect(db_username,db_password,dsn) cursor = DBCONN.cursor() query_add_data = """UPDATE my_table SET d = :d, c = :c WHERE a = :a AND b = :b""" cursor.executemany(query_add_data, data) DBCONN.commit() # 操作完成后关闭资源 cursor.close() DBCONN.close()
方案2:使用位置绑定
将SQL改为位置占位符,同时按SQL要求的顺序提取对应列的值:
import pandas as pd import cx_Oracle d = {'a': ['first', 'second'], 'b': [3, 4], 'c': ['2021-01-01', '2021-01-02'], 'd':[1.1,2.2], 'e':[5,6] } df = pd.DataFrame(data=d) # 按SQL参数顺序提取列:d、c、a、b,转列表 data = df[['d','c','a','b']].values.tolist() DBCONN = cx_Oracle.connect(db_username,db_password,dsn) cursor = DBCONN.cursor() # 用位置占位符:1、:2、:3、:4对应参数顺序 query_add_data = """UPDATE my_table SET d = :1, c = :2 WHERE a = :3 AND b = :4""" cursor.executemany(query_add_data, data) DBCONN.commit() # 操作完成后关闭资源 cursor.close() DBCONN.close()
内容的提问来源于stack exchange,提问作者Ferhat
相关产品推荐
相关产品推荐

