如何在Python中使用pyodbc运行未修改的T-SQL脚本
解决pyodbc执行含GO的T-SQL脚本问题(无需修改原脚本)
核心原因
GO并非SQL Server原生支持的T-SQL语法,它是SSMS、sqlcmd等工具的批处理分隔符。SSMS会自动将GO分隔的内容拆分成独立批处理发送给数据库引擎,但pyodbc会把包含GO的整段脚本直接提交,导致引擎识别错误。
可行解决方案
方法1:调用sqlcmd命令行工具执行
sqlcmd是微软官方工具,原生支持解析GO分隔符,完全兼容SSMS脚本格式,且无需修改原脚本文件。通过Python的subprocess模块调用即可:
import subprocess # 配置参数 server = "你的SQL Server实例名" db = "db_test" user = "你的用户名" pwd = "你的密码" script_path = "path/to/your/script.sql" # 构建sqlcmd命令 cmd = [ "sqlcmd", "-S", server, "-d", db, "-U", user, "-P", pwd, "-i", script_path ] # 执行并捕获结果 execution_result = subprocess.run(cmd, capture_output=True, text=True) # 输出结果 print("执行输出:\n", execution_result.stdout) if execution_result.stderr: print("错误信息:\n", execution_result.stderr)
注意:需确保系统已安装sqlcmd工具,通常随SQL Server客户端工具或ODBC驱动配套安装。
方法2:内存中拆分批处理执行(不修改原文件)
如果不想依赖外部工具,可以在Python中读取脚本后,在内存里按GO拆分批处理再逐个执行,原脚本文件保持完全不变:
import pyodbc # 建立数据库连接 conn = pyodbc.connect( "DRIVER={ODBC Driver 17 for SQL Server};" "SERVER=你的实例名;" "DATABASE=db_test;" "UID=你的用户名;" "PWD=你的密码;" ) cursor = conn.cursor() # 读取脚本内容 with open("path/to/your/script.sql", "r", encoding="utf-8") as f: script_content = f.read() # 拆分批处理(忽略注释和空行中的GO) batches = [] current_batch = [] for line in script_content.splitlines(): stripped_line = line.strip().upper() # 跳过空行和单行注释中的GO if not stripped_line or stripped_line.startswith("--"): current_batch.append(line) continue # 遇到GO则结束当前批处理 if stripped_line == "GO": if current_batch: batches.append("\n".join(current_batch)) current_batch = [] else: current_batch.append(line) # 添加最后一个未闭合的批处理 if current_batch: batches.append("\n".join(current_batch)) # 逐个执行批处理 for batch in batches: if batch.strip(): cursor.execute(batch) conn.commit() # 关闭连接 cursor.close() conn.close()
内容的提问来源于stack exchange,提问作者Djonathan Krause
相关产品推荐
相关产品推荐

