c# - SqlCommand() ExecuteNonQuery() 截断命令文本

标签 c# sqlcommand sqlclient

我正在构建自定义数据库部署实用程序,我需要读取包含 sql 脚本的文本文件并针对数据库执行它们。

非常简单的东西,到目前为止还不错。

但是我遇到了一个障碍,文件的内容被成功且完整地读取,但是一旦传递到 SqlCommand 然后使用 SqlCommand.ExecuteNonQuery 执行,只有部分脚本被执行。

我启动了 Profiler 并确认我的代码没有通过所有脚本。

    private void ExecuteScript(string cmd, SqlConnection sqlConn, SqlTransaction trans)
    {

        SqlCommand sqlCmd = new SqlCommand(cmd, sqlConn, trans);
        sqlCmd.CommandType = CommandType.Text;
        sqlCmd.CommandTimeout = 9000000; // for testing
        sqlCmd.ExecuteNonQuery();

    }

    // I call it like this, readDMLScript contains 543 lines of T-SQL
    string readDMLScript = ReadFile(dmlFile);
    ExecuteScript(readDMLScript, sqlConn, trans);

最佳答案

是的,每个人在第一次开始将 SQL 脚本文件的内容发送到数据库时都会遇到这个问题。

GO 不是 T-SQL 命令。它是所有 Microsoft 交互式 SQL 工具(Management Studio、isql、osql)都能识别的批处理结束标记。为了处理它,您必须编写自己的解析器来分解 GO 语句之间文件中的每个文本 block ,并将它们作为单独的命令提供给数据库。

如何实现解析器取决于您。它可以是简单的(一次读取每一行,检测只包含 GO 和空格的行)或复杂的(标记所有语句并确定 GO 是一个真正的语句或字符串或多行注释中的一些文本)。

我个人选择了第一个选项。它可以毫不费力地处理您可能遇到的所有 SQL 文件的 99%。如果您想全力以赴编写一个分词器,我相信很多人已经做过了,只需谷歌一下即可。

例子:

using(var reader = new SqlBatchReader(new StreamReader(dmlFile))) {
    string batch;
    while((batch = reader.ReadBatch()) != null) {
        var cmd = new SqlCommand(batch, conn, trans) { CommandType = CommandType.Text };
        cmd.ExecuteNonQuery();
    }
}

class SqlBatchReader : IDisposable {
    private TextReader _reader;
    public SqlBatchReader(TextReader reader) {
        _reader = reader;
    }
    /// <summary>
    /// Return the next command batch in the file, or null if end-of-file reached.
    /// </summary>
    public string ReadBatch() {
        // TODO: Implement your parsing logic here.
    }
}

关于c# - SqlCommand() ExecuteNonQuery() 截断命令文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2456552/

相关文章:

c# - 关闭记录集后是否必须处理 SqlCommand?

c# - 参数化 SqlCommand - 指定 SqlDbType 的优势?

C# 使用 SqlCommand.Parameters 更新表

c# - Microsoft.Data.SqlClient - 登录前握手错误

c# - (C#/C++ CLI) 是否可以保护我的 C++ CLI 程序集不被其他 .NET 项目使用?

c# - Silverlight ChildWindow 在回调时未正确关闭

c# - 这段代码有什么问题。为什么我不能使用 SqlConnection?

c# - Selenium WebDriver : how to count number of DIV elements in a list

c# - unattend.xml 架构的位置