Python操作Firebird遇firebirdsql.OperationalError:字符串"?"转换错误
Firebird参数化更新SQL执行报错问题
问题描述
我用以下代码通过字典键值对构建SQL更新语句:
record_number = 627 temp_dict = { "FOO": 752, "BAR": "test", "I": "zzzzz", "Hate": "tesname", "SQL": "testsomethingesle", "SO": "commentlol", "MCUH": "asadsa", "FILLING": "zzzzzz", "NAME": "''", } update_query = ( "UPDATE table_name SET {}".format( ", ".join("{} = '?'".format(k) for k in temp_dict) ) + " WHERE RECNUM = '" + str(record_number) + "';" ) update_values = tuple(temp_dict.values()) cur.execute(update_query, update_values)
生成的update_query和update_values看起来没问题,但执行时返回错误:
firebirdsql.OperationalError: conversion error from string "?"
我理解?是占位符,传入元组后应该被替换,请问哪里出错了?
问题原因与解决方法
- 错误核心:你给参数占位符
?加了单引号,Firebird的参数化查询中,占位符不需要额外包裹引号。驱动会根据参数的类型自动处理引号和转义,手动加单引号后,数据库会把'?'当成普通字符串字面量而非占位符,因此尝试把字符串"?"转换为字段对应类型时失败。 - 修正步骤:
- 去掉SET子句中占位符的单引号,将
"{} = '?'".format(k)改为"{} = ?".format(k) - WHERE子句中的
RECNUM也改用参数化方式传递,既避免字符串拼接的SQL注入风险,也保持参数化逻辑的一致性
- 去掉SET子句中占位符的单引号,将
修正后的代码
record_number = 627 temp_dict = { "FOO": 752, "BAR": "test", "I": "zzzzz", "Hate": "tesname", "SQL": "testsomethingesle", "SO": "commentlol", "MCUH": "asadsa", "FILLING": "zzzzzz", "NAME": "''", } # 构建SET子句,占位符不加单引号 set_clause = ", ".join("{} = ?".format(k) for k in temp_dict) # WHERE子句也使用占位符 update_query = f"UPDATE table_name SET {set_clause} WHERE RECNUM = ?;" # 把record_number加入参数元组 update_values = tuple(temp_dict.values()) + (record_number,) cur.execute(update_query, update_values)
内容的提问来源于stack exchange,提问作者P_stack_gprogram
相关产品推荐
相关产品推荐

