我遇到需要重复执行存储过程的情况 现在这个过程(spMAIN)里面有一个游标,它从表中查找一个值为T1,具有以下结构
ID Status
---- --------
1 New
2 New
3 success
4 Error
现在光标会查找状态为“新建”的所有行
现在在处理时,如果光标的那个实例遇到错误,另一个SP说需要调用spError,T1中的'Status'列需要更新为'Error'并且需要再次调用spMAIN重复这个过程,寻找带有'new'的行
我该怎么办? 另外,当我们在它的时候,如果SP内部有其他SP,如果任何一个SP引发错误,同样需要做什么,T1表需要更新('错误')和spMAIN需要再次召集。
你能推荐什么吗?这是一些代码
ALTER PROC zzSpMain
AS
BEGIN
DECLARE @id INT
BEGIN TRY
IF EXISTS ( SELECT *
FROM dbo.zzTest
WHERE istatus = 'new' )
BEGIN
DECLARE c CURSOR
FOR SELECT id
FROM zztest
WHERE istatus = 'new'
OPEN c
FETCH NEXT FROM c INTO @id
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT @id
IF @id = 2
BEGIN
UPDATE zztest
SET istatus = 'error'
WHERE id = @id
RAISERROR ( 'Error occured', 16,
1 )
END
UPDATE zztest
SET istatus = 'processed'
WHERE id = @id
FETCH NEXT FROM c INTO @id
END
CLOSE c
DEALLOCATE c
END
END TRY
begin CATCH
EXEC zzSpError
END CATCH
END
答案 0 :(得分:2)
您可以使用从SQL Server 2005开始内置于SQL Server中的TRY CATCH功能来执行错误处理。我建议您重新评估查询逻辑并查看类似SQL CLR或MERGE语句的内容。从样本代码来看,这应该是一条特别容易的路径。
答案 1 :(得分:2)
所有这个框架似乎都很好,所以我不确定你的问题是什么(如果你有很多嵌套的SP,则TRY / CATCH并重新抛出错误。)
然而,首选基于集合的方法。如果您可以提供更多的要求,我们可能会建议更容易。通常,对于轮询类型方案,我通常使用代理作业来操作整个新行集(可能使用游标),或者您可以为它们分配批号并开始处理该批处理。当下一次代理程序作业触发时,只有没有批处理的新行将被分配另一个批次,该批次将被终止并被处理。
但又不了解你的潜在动机...