返回已处理记录号的SQL Server存储过程

Ras*_*Ras 4 c# sql-server stored-procedures return timer

我有一个Winforms应用程序,它执行一个存储过程,检查几行(大约500k).为了通知用户已经处理了多少行,我需要一个存储过程,每n行返回一个值.例如,处理的每1000行(大多数是INSERT).

否则我只能在处理所有行时通知.任何提示如何解决这个问题?

我认为使用触发器或某些计划任务可能很有用,但我无法弄清楚如何实现它.

Rom*_*kar 8

So this is very interesting question. I've tried it about 5 years ago with no success, so this is a little challenge for me :) Well, here's is what I've got for you.

To send message from SQL Server you need to use raiserror command with nowait option. So I've wrote a stored procedure

create procedure sp_test
as
begin
    declare @i bigint, @m nvarchar(max)

     select @i = 1

     while @i < 10
     begin
         waitfor delay '00:00:01'
         select @m = cast(@i as nvarchar(max))
         raiserror(@m, 0, 0) with nowait
         select @i = @i + 1
     end
end
Run Code Online (Sandbox Code Playgroud)

If you try to execute it in SSMS, you'll see that message appearing in message section while procedure still works. Ok, we got messages from server. Now we need to process it on the client.

To do that, I've created a SQLCommand like this

SqlCommand cmd = new SqlCommand("sp_Test");
cmd.Connection = new SqlConnection("Server=HOME;Database=Test;Trusted_Connection=True;");
Run Code Online (Sandbox Code Playgroud)

now to catch a messages we using InfoMessage of SqlConnection object:

cmd.Connection.InfoMessage += Connection_InfoMessage;

static void Connection_InfoMessage(object sender, SqlInfoMessageEventArgs e)
{
    Console.WriteLine(e.Message);
}
Run Code Online (Sandbox Code Playgroud)

And now we're trying to display messages

cmd.Connection.Open();
try
{
    SqlDataReader r = cmd.ExecuteReader();
}
finally
{
    cmd.Connection.Close();
}
Run Code Online (Sandbox Code Playgroud)

SUCCESS :)

顺便说一下,你不能使用ExecuteNonQuery(),因为它在执行结束时返回连接的消息.此外,您可能希望在后台模式下运行查询,因此它不会锁定您的winform客户端.