Python Tkinter文本框数据插入SQL Server触发pyodbc参数错误
问题原因
报错本质是不同数据库驱动的参数占位符语法规则不兼容:
- sqlite3模块原生支持
:参数名格式的命名占位符,配合字典传参的写法可以正常运行,这也是之前操作SQLite时代码正常的原因 - pyodbc驱动连接SQL Server时,默认无法识别
:参数名格式的占位符,会将整段SQL判定为无参数语句,此时传入参数字典,就会触发pyodbc.ProgrammingError: ('The SQL contains 0 parameter markers, but 1 parameters were supplied', 'HY000')异常。
已经验证过数据库连接正常、读数据正常,说明连接配置完全没问题,问题仅出在参数绑定的语法上。
可行修复方案
两种写法都可以正常实现插入,按需选择即可:
方案1:使用问号占位符(兼容性最好)
pyodbc默认支持ANSI SQL标准的?作为顺序占位符,不需要记参数名,只需要保证传入值的顺序和SQL里占位符的顺序、表字段顺序一致即可。
更稳妥的写法是在INSERT语句中显式指定要插入的字段名,避免表结构变动导致值错位,修正后的插入代码如下:
# Insert into table cursor.execute( "INSERT INTO TEST_DISA_MAIN_TABLE (DENSITY_VALUE, DATE, TIME, CHART_VALUE) VALUES (?, ?, ?, ?)", ( DENSITY_VALUE.get(), DATE.get(), TIME.get(), CHART_VALUE.get() ) )
方案2:保留命名参数写法
如果不想维护参数顺序,可以改用T-SQL原生支持的@参数名格式作为命名占位符,pyodbc可以正常识别这种写法,仍然可以用字典传参:
# Insert into table cursor.execute( "INSERT INTO TEST_DISA_MAIN_TABLE (DENSITY_VALUE, DATE, TIME, CHART_VALUE) VALUES (@DENSITY_VALUE, @DATE, @TIME, @CHART_VALUE)", { 'DENSITY_VALUE': DENSITY_VALUE.get(), 'DATE': DATE.get(), 'TIME': TIME.get(), 'CHART_VALUE': CHART_VALUE.get(), } )
额外优化提示
贴出的代码末尾全局作用域下的conn.commit()和conn.close()是无效代码:conn是insertvalue函数内部定义的局部变量,全局位置无法访问,这两行可以直接删除,函数内部已经实现了事务提交和连接关闭的逻辑,不会影响插入功能。
内容的提问来源于stack exchange,提问作者ABCDave
相关产品推荐
相关产品推荐

