调用ExecuteNonQuery执行SQL脚本报错,含GO语法及初始化问题
问题分析与解决方案
错误原因解析
GO语法错误:GO是SQL Server Management Studio(SSMS)等工具的批处理分隔符,并非SQL Server原生支持的T-SQL语句。直接用ExecuteNonQuery执行包含GO的完整脚本时,数据库引擎无法识别该关键字,因此抛出语法错误。Command Text未初始化错误:
移除GO后出现该错误,大概率是以下原因之一:srSQL.ReadToEnd()读取到空字符串(比如脚本文件为空、读取权限不足)- 你的
m_DBConnection封装的ExecuteNonQuery方法对空/空白文本处理不当,导致命令文本未正确初始化 - 分支中重复调用
Open()导致连接状态异常,干扰命令执行
修复方案
方案1:复用批处理逻辑(推荐)
既然executeSQLBySequence=true的分支已经能正确处理GO并拆分脚本执行,直接在false分支复用这套逻辑即可,无需重新实现:
private void ExecuteFileBasedOnSequence(string fileToExecute, bool executeSQLBySequence = true) { m_DBConnection.BeginTransaction(); // 统一使用批处理逻辑,忽略参数差异 using (StreamReader srSQL = new StreamReader(fileToExecute)) { string sqlLine; StringBuilder sqlString = new StringBuilder(); while (!srSQL.EndOfStream) { sqlLine = srSQL.ReadLine(); if (!string.IsNullOrEmpty(sqlLine)) { // 处理带空格的GO行,比如" GO " if (string.Compare(sqlLine.Trim(), "GO", true) == 0) { if (!string.IsNullOrEmpty(sqlString.ToString().Trim())) { m_DBConnection.ExecuteNonQuery(sqlString.ToString()); } sqlString.Clear(); } else { sqlString.AppendLine(sqlLine); } } } // 处理脚本末尾没有GO结尾的剩余批处理 if (!string.IsNullOrEmpty(sqlString.ToString().Trim())) { m_DBConnection.ExecuteNonQuery(sqlString.ToString()); } } m_DBConnection.CommitTransaction(); }
注:原代码遗漏了脚本末尾无GO的情况,上述代码补充了该逻辑。
方案2:直接执行清理后的完整脚本(不推荐)
如果一定要用ReadToEnd()执行,需先手动移除所有GO关键字,同时确保脚本内容有效:
else { using (StreamReader srSQL = new StreamReader(fileToExecute)) { if (m_DBConnection != null) { // 读取脚本并过滤GO行 string fullScript = srSQL.ReadToEnd(); string[] lines = fullScript.Split(new[] { Environment.NewLine }, StringSplitOptions.None); StringBuilder cleanedScript = new StringBuilder(); foreach (string line in lines) { if (!string.Compare(line.Trim(), "GO", true) == 0) { cleanedScript.AppendLine(line); } } string finalScript = cleanedScript.ToString().Trim(); if (!string.IsNullOrEmpty(finalScript)) { // 检查连接状态,避免重复打开 if (m_DBConnection.State != ConnectionState.Open) { m_DBConnection.Open(); } m_DBConnection.ExecuteNonQuery(finalScript); } } } }
额外注意:事务中无需重复调用Open(),BeginTransaction()通常会自动打开连接;必须确保清理后的脚本非空,避免触发"Command text未初始化"错误。
额外优化建议
- 添加异常捕获:在事务逻辑外包裹
try-catch块,执行失败时调用m_DBConnection.RollbackTransaction()回滚事务 - 日志记录:对执行的脚本内容、异常信息进行日志记录,便于排查问题
内容的提问来源于stack exchange,提问作者nikhil
相关产品推荐
相关产品推荐

