출처 : http://www.jimmcleod.net/blog/index.php/2010/07/21/using-raiserror-for-progress-messages/
굉장히 느린 배치 같은 걸 프로시저로 돌릴 경우에
이게 어디까지 실행되고 있는지 모를 때가 있다.
게다가 해당 프로시저를 프로그램으로 실행하면 어디까지 왔는지 궁금한 경우도 많다.
이때 해당 프로시저에서 중간중간 메시지를 보내주고,
프로그램에선 이걸 중간중간 읽어서 Progress 같은 걸 구현할 수 있다.
아래 소스 중 해당 winform에는 버튼하나와 textbox 하나가 들어가있다.
use dbname
go
ALTER PROCEDURE dbo.InfoMsgTest
AS
DECLARE @i int;
SET @i = 1;
WHILE @i < 21
BEGIN
RAISERROR('%d', 0, 1, @i) WITH NOWAIT;
-- Do some processing!
WAITFOR DELAY '00:00:01';
SET @i = @i + 1;
END
GO
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace SqlMsgTest
{
//http://www.jimmcleod.net/blog/index.php/2010/07/21/using-raiserror-for-progress-messages/
public partial class Form1 : Form
{
private delegate void ReportProgress(string str);
public Form1()
{
InitializeComponent();
backgroundWorker1.DoWork += new DoWorkEventHandler(ExecSql);
backgroundWorker1.RunWorkerCompleted += (o, i) => { MessageBox.Show("end"); button1.Enabled = true; };
}
private void button1_Click(object sender, EventArgs e)
{
button1.Enabled = false;
backgroundWorker1.RunWorkerAsync();
}
private void ExecSql(object sender, DoWorkEventArgs e)
{
SqlConnection conn = new SqlConnection("Data Source=(local);Initial Catalog=dbname;USER ID=sa;PASSWORD=1234;");
conn.InfoMessage += new SqlInfoMessageEventHandler(InfoMessage);
conn.Open();
SqlCommand cmd = new SqlCommand("exec dbo.InfoMsgTest", conn);
cmd.CommandTimeout = 120;
Console.WriteLine("Processing starting.");
cmd.ExecuteReader();
conn.Close();
Console.WriteLine("Processing complete.");
}
private void InfoMessage(object sender, SqlInfoMessageEventArgs e)
{
Console.WriteLine("Percent completed: " + e.Message + "%");
this.Invoke(new ReportProgress(ReportMessage), e.Message);
}
private void ReportMessage(string str)
{
this.textBox1.AppendText(str + "\r\n");
}
}
}