如何在MS SQL Server中了解存储过程的执行状态

4

我有一个很长的存储过程,如何知道它的执行状态?类似于50%已完成等等。我搜索了很多,但没有得到满意的结果。所以希望这不是可能的。我正在使用MS SQL Server 2008。如果不可用,我可以知道为什么不可用吗?

4个回答

5
你可以使用:

RAISERROR ('Some comment, immediate', 0, 1) WITH NOWAIT 

在此语句之后立即输出消息(不会生成错误消息)。


@Janis 谢谢你,所以只有在使用SSMS执行时才能看到值,对吗? - kbvishnu
1
最好的部分是:不需要!你可以从.NET中访问它们:https://dev59.com/OHRA5IYBdhLWcg3w9y10 - Jānis

3
不,至少没有以你描述的形式可用。这是因为很难知道存储过程内部要做什么(如果它调用其他存储过程怎么办?)以及需要多长时间,直到它尝试执行。
当然,你可以检查存储过程并看到它执行了“SELECT * FROM [TableName]”。
但是你还需要知道表的大小、返回的数据类型、磁盘访问速度、查询是否被缓存等等。
然后,如果另一个进程意外地锁定了记录,并且持续时间比平常长,该怎么办?你不知道那个锁将被持有多长时间,所以如何计算未知变量(时间)的百分比?
你唯一能做的就是在存储过程中设置“检查点”,在每个离散步骤之后打印消息或发送电子邮件或记录到表中,例如。
print getdate()
print 'Selecting from [Users]'

Select * from [Users]

print getdate()
print 'Selecting from [Clients]'

Select * from [Clients]

print getdate()
print 'Finished'

这是一个选项。但是考虑到存储过程正在事务下运行的情况。如果我们有一个日志表并尝试输入日期时间,但我们只能在事务之后看到它。因此,我们需要等待直到那时。我希望我是正确的。如果不对,请告诉我。 - kbvishnu
1
如果PRINT语句是唯一产生输出的内容,由于缓冲区的原因,您可能要等到整个过程完成才能收到任何输出。使用RAISERROR('Selecting from [Users]',10,1) WITH NOWAIT可以发送信息性消息,并且不会遇到缓冲问题。 - Damien_The_Unbeliever
@VeeKeyBee 是的,没错 - 如果一个 TRANSACTION 被回滚了,那么表日志记录的想法就会被撤销,但是一般的“检查点”方法仍然有效。 - Widor

2

如果您有一个.NET客户端应用程序,您可以使用以下C#语法接收服务器发送的大约进度消息:

    using (SqlConnection conn = new SqlConnection(...))
    {
        conn.FireInfoMessageEventOnUserErrors = true;
        conn.InfoMessage += new SqlInfoMessageEventHandler(conn_InfoMessage);
        using (SqlCommand comm = new SqlCommand("dbo.sp1", conn) 
               { CommandType = CommandType.StoredProcedure })
        {
            conn.Open(); 
            comm.ExecuteNonQuery();
        }
    }

    static void conn_InfoMessage(object sender, SqlInfoMessageEventArgs e)
    {
        // Process received message
    }

在服务器端,可以按照Janis在之前的回答中描述的方式发送消息:

    RAISERROR('33%%..', 10, 0) WITH NOWAIT

1

SQL Server 没有内置功能来检查存储过程的状态,但您可以编写类似的功能。在我们的情况下,我们创建了一个日志记录函数,在存储过程中的每个进程之后发布一条消息。

假设您有一个运行多个查询的存储过程:

SELECT *
FROM yourTable

UPDATE ...
SET ...

DELETE 
FROM ...

您可以在每个查询/进程之后设置一个步骤,将数据发布到日志表中:
SELECT *
FROM yourTable

-- log query
INSERT INTO LogTable (DateComplete, Status, TaskId)
VALUES (getdate(), 'Complete', 1)

UPDATE ...
SET ...

-- log query
INSERT INTO LogTable (DateComplete, Status, TaskId)
VALUES (getdate(), 'Complete', 2)

DELETE 
FROM ...

-- log query
INSERT INTO LogTable (DateComplete, Status, TaskId)
VALUES (getdate(), 'Complete', 3)

您可以通过在查询周围使用TRY...CATCH块来进一步操作,然后可以根据过程是否成功或失败来显示不同的消息。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接