C#处理SQL Server消息输出

Eri*_*ham 8 c# sql-server ssms data-access-layer

在SQL Server Management Studio中执行脚本时,通常会生成显示在消息窗口中的消息.例如,在运行数据库备份时:

处理率为10%.

处理率为20%.

等等...

为数据库'Sample'处理了1722608页,在文件1上处理了'Sampe'文件.

100%处理.

为数据库'Sample'处理了1页,在文件1上处理了'Sample_Log'文件.

BACKUP DATABASE在202.985秒(66.299 MB /秒)内成功处理了1722609页.

我希望能够在针对数据库运行SQL脚本的C#应用​​程序中显示这些消息.但是,我无法弄清楚如何在生成SQL时从SQL输出消息.有人知道怎么做这个吗?我必须使用哪个连接框架并不重要.我对LINQ,NHibernate,Entity Framework,ADO.Net,企业库比较熟悉,并且很乐意学习新的.

小智 7

这是我尝试的示例代码,它适用于我. http://www.dotnetcurry.com/ShowArticle.aspx?ID=344

请注意,您需要的代码实际上就是这部分:

cn.Open();
cn.InfoMessage += delegate(object sender, SqlInfoMessageEventArgs e)
{                                    
         txtMessages.Text += "\n" + e.Message;                                   
};
Run Code Online (Sandbox Code Playgroud)

这是e.Message不断将消息返回到txtMessages(您可以替换为TextBox或Label).

您还可以参考这篇文章: 使用进度备份SQL Server数据库

我的代码示例如下:

//The idea of the following code is to display the progress on a progressbar using the value returning from the SQL Server message. 
//When done, it will show the final message on the textbox. 
String connectionString = "Data Source=server;Integrated Security=SSPI;";
SqlConnection sqlConnection = new SqlConnection(connectionString);

public void DatabaseWork(SqlConnection con)
{
    con.FireInfoMessageEventOnUserErrors = true;
    //con.InfoMessage += OnInfoMessage;
    con.Open();
    con.InfoMessage += delegate(object sender, SqlInfoMessageEventArgs e)
    {
        //Use textBox due to textBox has Invoke function. You can also utilize other way. 
        this.textBox.Invoke(
            (MethodInvoker)delegate()
            {
                int num1;
                //Get the message from e.Message index 0 to the length of first ' '
                bool res = int.TryParse(e.Message.Substring(0, e.Message.IndexOf(' ')), out num1);

                //If the substring can convert to integer
                if (res)
                {
                    //keep updating progressbar
                    this.progressBar.Value = int.Parse(e.Message.Substring(0, e.Message.IndexOf(' ')));
                }
                else
                {
                    //Check status from message 
                    int succ;
                    succ = textBox.Text.IndexOf("successfully");
                    //or succ = e.Message.IndexOf("successfully");  //get result from e.Message directly
                    if (succ != -1) //If IndexOf find nothing, it will return -1
                    {
                        progressBar.Value = 100;
                        MessageBox.Show("Done!");
                    }
                    else
                    {
                        progressBar.Value = 0;
                        MessageBox.Show("Error, backup failed!");
                    } 
                }
            }
        );
    };
    using (var cmd = new SqlCommand(string.Format(
        "Your SQL Script"//,
        //QuoteIdentifier(databaseName),
        //QuoteString(Filename)//,
        //QuoteString(backupDescription),
        //QuoteString(backupName)
        ), con))
    {
        //Set timeout = 1200 seconds (equal 20 minutes, you can set smaller value for shoter time out. 
        cmd.CommandTimeout = 1200;
        cmd.ExecuteNonQuery();
    }
    con.Close();
    //con.InfoMessage -= OnInfoMessage;
    con.FireInfoMessageEventOnUserErrors = false;
}
Run Code Online (Sandbox Code Playgroud)

为了使进度条工作,您需要使用后台工作程序来实现它,您的应用程序不会冻结并突然完成100%.


Sas*_*nig 5

SqlConnection.InfoMessage当SQL服务器返回警告或信息性消息出现的事件。该网站显示了一种可能的实现方式。