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

时间:2012-07-10 13:56:14

标签: sql-server sql-server-2008 tsql

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

4 个答案:

答案 0 :(得分:5)

您可以使用:

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

在此声明后立即打印消息。 (它不会生成错误消息)。

答案 1 :(得分:3)

不,至少以您描述的形式无法使用。这是因为很难知道存储过程必须在内部执行什么(如果它调用其他存储过程会怎样?)以及需要多长时间,直到它尝试执行它为止。

当然,您可以检查过程并查看它SELECT * FROM [TableName]

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

然后,如果另一个进程意外锁定记录并且需要比平时更长的时间呢?你不知道锁定的持续时间 - 所以你如何计算未知变量的百分比(时间)?

您可以做的最好的事情是在您的过程中将“检查点”放入print消息或发送电子邮件或在每个离散步骤后登录表格,例如

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

Select * from [Users]

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

Select * from [Clients]

print getdate()
print 'Finished'

答案 2 :(得分: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

答案 3 :(得分: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块进一步解决此问题,然后您可以获得有关流程是否成功或失败的不同消息。