Click here to Skip to main content
15,880,608 members
Articles / Programming Languages / C#
Tip/Trick

SQL Connection message event handler use

Rate me:
Please Sign up or sign in to vote.
4.50/5 (3 votes)
25 Jul 2013CPOL2 min read 14.8K   6   5
This article will describe about SQLConnection Message Event Handler and BackugroundWorker functionlity.

Introduction

This article will describe how to backup a database of SQL Server and how to receive status messages send by SQL Server while backup process is running. BackgroundWorker functionality are also described in this article.

Using the code

Backup is an essential object while developing a program for client. Data may be corrupt in many cases, so we have to develop a program by which we can preserve user data on external media or computer.

This article describes about how to backup an SQL Server database. You will also learn about asynchronous functionality of BackgroundWroker class in this article.

I also want to introduce about SqlConnection class property FireInfoMessageEventOnUsersErrors working in this article. When SQL Server executes an command it sends status to application which can be caught by application.

In this article when Backup processes Status of backup in percentage will be received by application which is send by SQL Server to show progress bar value and percentage on label control.

Finally, this article doesn’t use any third party library/control to perform backup action. All classes used in this code are built-in .NET Framework. You can run this code without any problem and can incorporate in any application that uses SQL Server as backend to store data. 

Source code:

C#
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

using System.Data.Sql;
using System.Data.SqlClient;
using System.IO;
using System.Data.Common;

namespace BackupDatabase
{
    public partial class Form1 : Form
    {
        SqlConnection sCon = null;
        SqlCommand sCmd = null;
        SqlDataAdapter sAdpt = null;

        BackgroundWorker bWorker = null;
        bool bDone = true;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            cboAuth.SelectedIndex = 0;
            this.Height = 235;

            setWindowLocation();
        }

        private void bttnCancel_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void bttnBrowse_Click(object sender, EventArgs e)
        {
            folderDialog.Description = "Please select path";
            folderDialog.RootFolder = Environment.SpecialFolder.Desktop;

            if (folderDialog.ShowDialog() != DialogResult.Cancel)
                txtBackupLocation.Text = folderDialog.SelectedPath;
        }

        private void bttnConnect_Click(object sender, EventArgs e)
        {
            if (txtServer.Text.Trim() == string.Empty)
            {
                MessageBox.Show("Please select Server Name", 
                  "Connect to Server", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }
            else if (cboAuth.SelectedIndex==1)
            {
                if (txtUserName.Text.Trim() == string.Empty)
                {
                    MessageBox.Show("Please enter User Name", 
                      "Connect to Server", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return;
                }
                else if (txtPassword.Text.Trim() == string.Empty)
                {
                    MessageBox.Show("Please enter Password", 
                      "Connect to Server", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return;
                }
            }

            string sConnectionString = string.Empty;

            if (cboAuth.SelectedIndex == 1)
                sConnectionString = "Data Source=" + txtServer.Text + 
                  "; User Id=" + txtUserName.Text + "; Password=" + 
                  txtPassword.Text + "; Database=Master";
            else
                sConnectionString = "Data Source=" + txtServer.Text + 
                  "; Integrated Security=SSPI; Database=Master";

            try
            {
                sCon = new SqlConnection(sConnectionString);
                sCon.Open();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Connect to Server", 
                      MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            this.Height = 423;

            setWindowLocation();

            loadDatabaseList();
        }

        void setWindowLocation()
        {
            this.Top = (Screen.PrimaryScreen.Bounds.Height - this.Height) / 2;
            this.Left = (Screen.PrimaryScreen.Bounds.Width - this.Width) / 2;
        }

        void loadDatabaseList()
        {
            sCmd = new SqlCommand("select name from sys.databases order by name", sCon);
            sAdpt = new SqlDataAdapter(sCmd);

            DataSet ds = new DataSet();
            sAdpt.Fill(ds, "tblList");

            cboDatabaseList.DisplayMember = "name";
            cboDatabaseList.DataSource = ds.Tables[0];
        }

        private void bttnStart_Click(object sender, EventArgs e)
        {
            if (cboDatabaseList.SelectedIndex == -1)
            {
                MessageBox.Show("No database name found to backup", 
                  "Connect to Server", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return;
            }
            else if (txtBackupLocation.Text.Trim()==string.Empty)
            {
                MessageBox.Show("No backup location found to backup", 
                  "Connect to Server", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return;
            }

            bWorker = new BackgroundWorker();

            bWorker.WorkerReportsProgress = true;
            bWorker.WorkerSupportsCancellation = true;

            bWorker.DoWork += new DoWorkEventHandler(bWorker_DoWork);
            bWorker.ProgressChanged += new ProgressChangedEventHandler(bWorker_ProgressChanged);
            bWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bWorker_RunWorkerCompleted);

            BackupHelper bI = new BackupHelper(sCon,cboDatabaseList.Text, txtBackupLocation.Text);
            bWorker.RunWorkerAsync(bI);
        }

        void bWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            BackupHelper bI = (BackupHelper)e.Argument;

            bI.StartBackup(bWorker);
        }

        void bWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            pBar.Value = 0;
            lblPercent.Text = "0 %";

            if (bDone)
            {
                MessageBox.Show("Backup Complete !", 
                  "Connect to Server", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }

        void bWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            if (e.ProgressPercentage == -1)
            {
                bDone = false;
                bWorker.CancelAsync();
                MessageBox.Show(e.UserState.ToString(), 
                  "Connect to Server", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            else
            {
                pBar.Value = e.ProgressPercentage;
                lblPercent.Text = pBar.Value + " %";
            }
        }
    }

    public class BackupHelper
    {
        private SqlConnection sBackupConnection = null;
        private string sDatabaseName = null;
        private string sBackupLocation = null;

        BackgroundWorker bW = null;

        private SqlConnection BackupConnection
        {
            get
            {
                return sBackupConnection;
            }
            set
            {
                sBackupConnection = value;
            }
        }

        private string DatabaseName
        {
            get
            {
                return sDatabaseName;
            }
            set
            {
                sDatabaseName = value;
            }
        }

        private string BackupLocation
        {
            get
            {
                return sBackupLocation;
            }
            set
            {
                sBackupLocation = value;
            }
        }

        public BackupHelper()
        {

        }

        public BackupHelper(SqlConnection sBackupConnection, 
                string sDatabaseName, string sBackupLocation)
        {
            this.BackupConnection = new SqlConnection(sBackupConnection.ConnectionString);
            this.DatabaseName = sDatabaseName;
            this.BackupLocation = sBackupLocation;
        }

        public void StartBackup(BackgroundWorker bW)
        {
            this.bW = bW;

            sBackupConnection.FireInfoMessageEventOnUserErrors = true;
            sBackupConnection.InfoMessage += OnInfoMessage;
            sBackupConnection.Open();

            StringBuilder sb = new StringBuilder();

            sb.AppendFormat(@"BACKUP DATABASE [{0}] TO  DISK = N'{1}' WITH " + 
                @"DESCRIPTION = N'{2}', NOFORMAT, NOINIT, NOSKIP, REWIND, NOUNLOAD,  STATS = 1",
                this.DatabaseName, Path.Combine(this.BackupLocation, 
                this.DatabaseName + ".bak"), this.DatabaseName + " full backup");

            SqlCommand sqlCmd = new SqlCommand(sb.ToString(), sBackupConnection);
            sqlCmd.CommandTimeout = 10000;
            sqlCmd.ExecuteNonQuery();

            sBackupConnection.Close();
        }

        protected void OnInfoMessage(object sender, SqlInfoMessageEventArgs e)
        {
            if (e.Message.Contains("percent processed."))
            {
                int iPercent = 0;
                int.TryParse(e.Message.Replace("percent processed.", ""), out iPercent);

                bW.ReportProgress(iPercent, null);
            }
            else
            {
                #region COMMENT

                string CommandStatus = string.Empty;

                foreach (SqlError info in e.Errors)
                    if (info.Class > 10)
                        CommandStatus += e.Message + Environment.NewLine;

                if (CommandStatus != string.Empty)
                {
                    bW.ReportProgress(-1, CommandStatus);
                }

                #endregion
            }
        }
    }
}

This statement will confirm that the child thread can send data to it's parent thread.

C#
bWorker.WorkerReportsProgress = true;

This statement specifies that the child thread can be interrupt while running.

C#
bWorker.WorkerSupportsCancellation = true;

This statement specifies that method bWorker_DoWork will be execute when RunWorkerAsync method will be call.

C#
bWorker.DoWork += new DoWorkEventHandler(bWorker_DoWork);

This statement specifies that method bWorker_ProgressChanged will be execute when child thread call ReportProgress method.

C#
bWorker.ProgressChanged += new ProgressChangedEventHandler(bWorker_ProgressChanged);

Finally... These following lines of code will specifies the SqlConnection class can send message when any SqlCommand fires on it, and which method will be call Specifies by InfoMessage property.

C#
sBackupConnection.FireInfoMessageEventOnUserErrors = true;
sBackupConnection.InfoMessage += OnInfoMessage;

Finally, I think this article will help to improve knowledge of beginners and developers also. Thanks...

Next Update

In the next version of this article I will introduce the restore functionality. 

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer Professional Softec Pvt. Ltd.
India India
Working in Jaipur at Professional Softec Pvt. Ltd. Since Nov, 2006.
Mostly working in asp.net 2.0, javascript, sqlserver 2005/2008, jquery etc.

Comments and Discussions

 
GeneralMy vote of 5 Pin
Dineshshp16-Aug-13 19:07
professionalDineshshp16-Aug-13 19:07 
GeneralMy vote of 5 Pin
Dineshshp16-Aug-13 19:07
professionalDineshshp16-Aug-13 19:07 
QuestionHow to download? Pin
Roberto Guerzoni25-Jul-13 21:11
professionalRoberto Guerzoni25-Jul-13 21:11 
AnswerRe: How to download? Pin
Dineshshp1-Aug-13 21:18
professionalDineshshp1-Aug-13 21:18 
I Have attached downloadable file(s) but not showing here. You can copy this code here...

Thanks for like this code...

DineshT
DineshT

SuggestionBackup progress Pin
Paw Jershauge25-Jul-13 5:17
Paw Jershauge25-Jul-13 5:17 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.