Python使用oracledb的executemany()执行UPDATE语句时抛出ORA-01036错误的问题求助
Python使用oracledb的executemany()执行UPDATE语句时抛出ORA-01036错误的问题求助
我来帮你排查这个问题,你遇到的ORA-01036: illegal variable name/number错误其实是绑定变量的写法出了问题,咱们一步步拆解分析:
问题现象
你尝试用executemany()批量执行UPDATE操作时报错,但通过循环逐行调用execute()就能正常完成更新:
报错的代码示例
update_data_df = read_docs_df[['CONTRACT_NUM', 'DOCID']].copy() cur_upd = conn_dwh.cursor() dataUpdate = [tuple(i) for i in update_data_df.values] print(dataUpdate) # 输出:[('П/0097232-Д8', 7481640), ('П/0117840-Д2', 7131468), ('1/А-БПИ/Нск-Д1', 6819213), ('П/0082021-Д5', 7425529)] sqlTxt = "UPDATE USERBOX_MIDDLE_OFFICE.rvp_doc_partner_to_archive SET DOCID = :2 WHERE CONTRACT_NUM = ':1'" cur_upd.executemany(sqlTxt, dataUpdate) updated_docs = cur_upd.rowcount conn_dwh.commit() cur_upd.close()
执行后触发错误:DatabaseError: ORA-01036: illegal variable name/number
正常工作的代码示例
update_data_df = read_docs_df[['CONTRACT_NUM', 'DOCID']].copy() cur_upd = conn_dwh.cursor() updated_docs = 0 for row in update_data_df.itertuples(): sqlTxt = f"UPDATE USERBOX_MIDDLE_OFFICE.rvp_doc_partner_to_archive SET DOCID = {row.DOCID} WHERE CONTRACT_NUM = '{row.CONTRACT_NUM}'" print(sqlTxt) cur_upd.execute(sqlTxt) updated_docs += cur_upd.rowcount conn_dwh.commit() cur_upd.close()
错误原因分析
问题核心在你报错代码里的SQL语句:
UPDATE USERBOX_MIDDLE_OFFICE.rvp_doc_partner_to_archive SET DOCID = :2 WHERE CONTRACT_NUM = ':1'
你给绑定变量:1包裹了单引号,变成了':1'——这会让数据库把它当作普通字符串字面量,而非需要绑定值的变量。这样数据库只能识别到:2这1个绑定变量,但你传入的每个元组有2个值,变量数量不匹配,直接触发了ORA-01036错误。
另外补充:虽然循环的代码能运行,但用f-string直接拼接SQL存在SQL注入风险,也容易因特殊字符(比如单引号)引发语法错误,所以更推荐用executemany()加正确的绑定变量写法。
修正后的代码
只需要去掉绑定变量:1外面的单引号,让它保持纯绑定变量即可,同时你数据元组的顺序(CONTRACT_NUM, DOCID)和SQL里的:1、:2是对应的,无需调整顺序:
update_data_df = read_docs_df[['CONTRACT_NUM', 'DOCID']].copy() cur_upd = conn_dwh.cursor() dataUpdate = [tuple(i) for i in update_data_df.values] print(dataUpdate) # 修正后的SQL:去掉':1'的单引号 sqlTxt = "UPDATE USERBOX_MIDDLE_OFFICE.rvp_doc_partner_to_archive SET DOCID = :2 WHERE CONTRACT_NUM = :1" cur_upd.executemany(sqlTxt, dataUpdate) updated_docs = cur_upd.rowcount conn_dwh.commit() cur_upd.close()
这样执行executemany()就能正常批量更新数据,既高效又安全。
(环境:Python 3.9,oracledb 1.4.1)
内容来源于stack exchange
相关产品推荐
相关产品推荐

