SQL Server 2000:如何退出存储过程?
Posted
技术标签:
【中文标题】SQL Server 2000:如何退出存储过程?【英文标题】:SQL Server 2000: How to exit a stored procedure? 【发布时间】:2010-12-24 04:30:50 【问题描述】:如何在存储过程中退出?
我有一个存储过程,我想提早退出(同时尝试调试它)。我尝试调用RETURN
和RAISERROR
,sp 继续运行:
CREATE PROCEDURE dbo.Archive_Session @SessionGUID uniqueidentifier AS
print 'before raiserror'
raiserror('this is a raised error', 18, 1)
print 'before return'
return -1
print 'after return'
[snip]
我知道它会继续运行,因为我遇到了进一步的错误。我没有看到我的任何打印件。如果我注释掉大部分存储过程:
CREATE PROCEDURE dbo.Archive_Session @SessionGUID uniqueidentifier AS
print 'before raiserror'
raiserror('this is a raised error', 18, 1)
print 'before return'
return -1
print 'after return'
/*
[snip]
*/
然后我没有得到我的错误,我看到了结果:
before raiserror
Server: Msg 50000, Level 18, State 1, Procedure Archive_Session, Line 5
this is a raised error
before return
所以问题是:如何摆脱 SQL Server 中的存储过程?
【问题讨论】:
"欢迎来到加州酒店..." =) 呃? (填充以使我的“Guh?”查询至少 15 个字符长) 哦,等等,我明白了……“你永远不能离开”。这似乎有很多代码,但这是我发现的最好的方法。
ALTER PROCEDURE Procedure
AS
BEGIN TRY
EXEC AnotherProcedure
END TRY
BEGIN CATCH
DECLARE @ErrorMessage NVARCHAR(4000);
DECLARE @ErrorSeverity INT;
DECLARE @ErrorState INT;
SELECT
@ErrorMessage = ERROR_MESSAGE(),
@ErrorSeverity = ERROR_SEVERITY(),
@ErrorState = ERROR_STATE();
RAISERROR (@ErrorMessage, -- Message text.
@ErrorSeverity, -- Severity.
@ErrorState -- State.
);
RETURN --this forces it out
END CATCH
--Stuff here that you do not want to execute if the above failed.
END --end procedure
【讨论】:
【参考方案2】:您可以使用RETURN
立即停止执行存储过程。引自Books Online:
无条件退出查询或 程序。 RETURN 是立即的,并且 完整,可随时使用 退出程序、批次或 语句块。声明 follow RETURN 不会被执行。
出于偏执,我尝试了您的示例,它确实输出了 PRINT 并立即停止执行。
【讨论】:
你能想到为什么调用return
不会无条件退出过程吗?
如果您已经开始一个事务或有一个打开的游标,请小心退出过程。
我不能 - 您能否发布一个完整的存储过程示例,当您运行它时,不会在返回时立即退出?只是为了让我们有一个确切的例子来回顾
这可以在 TRY-CATCH 中使用吗?因此,如果我在 TRY 中调用 RETURN,它会执行 CATCH 吗?【参考方案3】:
这是因为您没有 BEGIN
和 END
语句。你不应该看到打印或运行此语句的错误,只有 Statement Completed
(或类似的东西)。
【讨论】:
【参考方案4】:我知道为什么RETURN
不是无条件地从存储过程返回。我看到的错误是存储过程正在编译 - 而不是在执行时。
考虑一个虚构的存储过程:
CREATE PROCEDURE dbo.foo AS
INSERT INTO ExistingTable
EXECUTE LinkedServer.Database.dbo.SomeProcedure
即使这个存储过程包含错误(可能是因为对象的列数不同,可能表中有时间戳列,可能存储过程不存在),您仍然可以 保存。您可以保存它,因为您引用的是链接服务器。
但是当你真正执行存储过程时,SQL Server 会编译它,并生成一个查询计划。
我的错误不是发生在第 114 行,而是 在第 114 行。SQL Server 无法编译存储过程,这就是它失败的原因。
这就是RETURN
没有返回的原因,因为它甚至还没有开始。
【讨论】:
当然你不应该在没有指定列的情况下编写插入代码。 当然我想在不指定列的情况下编写插入代码。现在我必须指定它们,添加到源表的其他列将丢失。【参考方案5】:这在这里有效。
ALTER PROCEDURE dbo.Archive_Session
@SessionGUID int
AS
BEGIN
SET NOCOUNT ON
PRINT 'before raiserror'
RAISERROR('this is a raised error', 18, 1)
IF @@Error != 0
RETURN
PRINT 'before return'
RETURN -1
PRINT 'after return'
END
go
EXECUTE dbo.Archive_Session @SessionGUID = 1
返回
before raiserror
Msg 50000, Level 18, State 1, Procedure Archive_Session, Line 7
this is a raised error
【讨论】:
这似乎是一种更简洁/更快的输入方式。【参考方案6】:把它放在TRY/CATCH
。
当 RAISERROR 以严重性运行时 TRY 块中的 11 或更高,它 将控制权转移给相关的 捕获块
参考:MSDN。
编辑:这适用于 MSSQL 2005+,但我看到您现在已经澄清您正在使用 MSSQL 2000。我将把它留在这里以供参考。
【讨论】:
+1 SQL Server 2000,所以无助于回答我的问题。但对于尝试进行异常处理的人来说,这可能是一种有用的技术 我真的很喜欢这个。但是......叹息......其他新东西要学习。【参考方案7】:除非您指定 20 或更高的严重性,raiserror
不会停止执行。请参阅MSDN documentation。
正常的解决方法是在每个raiserror
之后包含一个return
:
if @whoops = 1
begin
raiserror('Whoops!', 18, 1)
return -1
end
【讨论】:
“从 19 到 25 的严重级别只能由 sysadmin 固定服务器角色的成员或具有 ALTER TRACE 权限的用户指定。”来自 MSDN @Forgotten Semicolon: 是的,所以在大多数情况下,raiserror
因其功能出乎意料的功能而获奖(以及金错字奖杯)
+1。不是这个问题的真正答案,而是“答案很有用”以上是关于SQL Server 2000:如何退出存储过程?的主要内容,如果未能解决你的问题,请参考以下文章
如何从 SQL Server 2000 调用 MySQL 存储过程?
用SQL创建存储过程的题目(SQL SERVER2000下)
在 SQL Server 2000 中删除存储过程的语法是啥?