Sql server 如何知道MS SQL Server中存储过程的执行状态

Sql server 如何知道MS SQL Server中存储过程的执行状态,sql-server,sql-server-2008,tsql,Sql Server,Sql Server 2008,Tsql,我有一个很长的存储过程,如何知道它的执行状态?大约完成了50%等等。 我搜索了很多,没有得到任何满意的结果。所以希望这是不可能的。我使用的是MS SQL Server 2008。如果它不可用 我可以知道没有的原因吗 不,至少在您描述的形式中不可用。这是因为很难知道一个存储过程在内部要做什么,如果它调用其他存储过程呢?以及需要多长时间,直到它尝试这样做 当然,您可以检查proc并查看它是否从[TableName]中选择* 但是,您需要知道表的大小、返回的数据类型、磁盘访问速度、查询是否已缓存等 然

我有一个很长的存储过程,如何知道它的执行状态?大约完成了50%等等。 我搜索了很多,没有得到任何满意的结果。所以希望这是不可能的。我使用的是MS SQL Server 2008。如果它不可用
我可以知道没有的原因吗

不,至少在您描述的形式中不可用。这是因为很难知道一个存储过程在内部要做什么,如果它调用其他存储过程呢?以及需要多长时间,直到它尝试这样做

当然,您可以检查proc并查看它是否从[TableName]中选择*

但是,您需要知道表的大小、返回的数据类型、磁盘访问速度、查询是否已缓存等

然后,如果另一个进程意外地锁定了一个记录,并且花费的时间比平时长,该怎么办?您不知道该锁将被保持多长时间,那么如何计算未知变量时间的百分比呢

你能做的最好的事情就是在你的进程中设置“检查点”,在每个离散步骤后打印消息或发送电子邮件或登录表格,例如

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

Select * from [Users]

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

Select * from [Clients]

print getdate()
print 'Finished'
您可以使用:

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

在此语句之后立即打印消息。它不会生成错误消息。

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块,您可以进一步了解这一点。然后,您可以使用不同的消息来说明进程是成功的还是失败的。

如果您有.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

这是一个选择。但是考虑SP在事务下运行的情况。如果我们有一个日志表,并且我们试图输入日期时间,但是我们只能在事务之后看到。所以我们需要等到那时。我希望我是对的。请告诉我这是否是错误的。如果打印语句是唯一产生输出的东西,由于缓冲,在整个过程完成之前,您可能不会收到任何输出。RAISERROR'Selecting from[Users]”,10,1 WITH NOWAIT发送一条信息性消息,不会出现缓冲问题。@VeeKeyBee是的,没错-如果事务回滚,表记录想法将被撤消,但常规的“检查点”方法仍然有效。@Janis谢谢,因此,我们只能在使用SSMS执行时才能看到该值。对吧?最好的部分是:不!您可以从.NET访问它们: