如何让pyodbc将用户输入作为存储过程参数?解决类型转换报错
解决pyodbc调用SQL Server存储过程时nvarchar转decimal失败的问题
核心问题出在你调用存储过程的方式——你直接把Python变量名写进了SQL字符串里,SQL Server会把d1、quantity这些当成字符串字面量(也就是nvarchar类型)去处理,自然没法把字符串转成decimal(18,2),这才报了错。
正确的解决步骤:
- 用参数占位符传递变量:pyodbc支持用
?作为参数占位符,把Python变量通过参数列表传给cursor.execute(),这样pyodbc会自动处理类型映射,不用你手动转换。 - 优先用decimal.Decimal处理数值:float类型存在精度丢失问题,用
decimal.Decimal更匹配SQL Server的decimal类型,同时要确保用户输入的是合法数字(建议加输入验证)。
修正后的代码片段:
# 先导入decimal模块(你之前没导入,需要加上) from decimal import Decimal # 获取输入并转换类型(增加基础输入验证) d1 = datetime.now() person = os.getlogin() material = self.Material.GetValue() # 转换为Decimal,同时处理可能的输入错误 try: quantity = Decimal(self.Quant.GetValue()) cost = Decimal(self.Cost.GetValue()) except ValueError: # 这里可以加弹窗提示用户输入合法数字 wx.MessageBox("数量或成本必须是有效的数字!", "输入错误", wx.OK | wx.ICON_ERROR) # 终止后续操作 return conn= pyodbc.connect('Driver=SQL Server Native Client 11.0;' 'Server=J211;' 'Database=T3_Forecasting_TRS;' 'Trusted_Connection=yes;') cursor = conn.cursor() # 用?作为占位符,参数放在execute的第二个参数里 cursor.execute("EXEC SP_KC_RunMOQRules ?, ?, ?, ?, ?", (d1, person, material, quantity, cost)) # 注意commit是方法,要加括号 conn.commit() cursor.close() conn.close()
额外提示:
- 永远不要直接把变量拼进SQL语句里,除了类型问题,还会有SQL注入风险
- 记得用完连接和游标后关闭,或者用
with语句自动管理连接:
with pyodbc.connect('Driver=SQL Server Native Client 11.0;' 'Server=J211;' 'Database=T3_Forecasting_TRS;' 'Trusted_Connection=yes;') as conn: with conn.cursor() as cursor: cursor.execute("EXEC SP_KC_RunMOQRules ?, ?, ?, ?, ?", (d1, person, material, quantity, cost)) conn.commit()
内容的提问来源于stack exchange,提问作者Katelyn Clasper
相关产品推荐
相关产品推荐

