Django调用MSSQL存储过程遇参数格式化错误及传值问题求助
解决Django调用MSSQL存储过程的参数绑定问题
问题原因分析
- 直接在CALL语句中写
P1,P2,P3时,数据库会将其视为字符串字面量,而非变量值,所以插入的是"P1"这类固定字符串。 - 使用
?作为占位符时,Django的MSSQL后端在debug模式下,会尝试用Python的%语法格式化SQL语句,但?不是Python的有效格式化占位符,因此触发TypeError: 字符串格式化时未转换所有参数。
解决方案
方案一:使用Django原生cursor.callproc方法(推荐)
这是Django官方推荐的存储过程调用方式,无需手动拼接SQL语句,参数绑定更安全可靠:
def test(request): if request.method == "POST": with connection.cursor() as cursor: P1 = request.data["p1"] P2 = request.data["p2"] P3 = request.data["p3"] params = (P1, P2, P3) print(params) try: # 调用存储过程,第一个参数为存储过程完整名称,第二个为参数元组 cursor.callproc("[dbo].[myStoredProcedure]", params) # 如果存储过程返回结果集,获取结果 result_set = cursor.fetchall() print(result_set) finally: cursor.close() return Response({"msg": "post"}) else: return Response({"msg": "get"})
方案二:修改占位符为%s
若坚持使用cursor.execute,需将MSSQL的占位符?替换为Python兼容的%s,避免debug模式下的格式化错误:
def test(request): if request.method == "POST": with connection.cursor() as cursor: P1 = request.data["p1"] P2 = request.data["p2"] P3 = request.data["p3"] params = (P1,P2,P3) print(params) try: # 用%s作为占位符,与Python字符串格式化语法兼容 cursor.execute("{CALL [dbo].[myStoredProcedure] (%s,%s,%s)}", params) if cursor.return_value == 1: result_set = cursor.fetchall() print(result_set) finally: cursor.close() return Response({"msg":"post"}) else: return Response({"msg": "get"})
注意事项
- 确保数据库连接配置正确,使用的是支持MSSQL的Django后端(如
django-mssql或django-pyodbc-azure)。 - 若存储过程包含输出参数,
callproc方法会自动处理,可通过cursor.fetchall()或检查cursor.return_value获取结果。
内容的提问来源于stack exchange,提问作者leauradmin
相关产品推荐
相关产品推荐

