Sql server SQL Server 2000:如何退出存储过程? 如何在存储过程中间退出?< /P>
我有一个存储过程,我希望尽早退出(同时尝试调试它)。我已尝试调用Sql server SQL Server 2000:如何退出存储过程? 如何在存储过程中间退出?< /P>,sql-server,tsql,stored-procedures,sql-server-2000,control-flow,Sql Server,Tsql,Stored Procedures,Sql Server 2000,Control Flow,我有一个存储过程,我希望尽早退出(同时尝试调试它)。我已尝试调用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 pr
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]
*/
CREATE PROCEDURE dbo.foo AS
INSERT INTO ExistingTable
EXECUTE LinkedServer.Database.dbo.SomeProcedure
然后我没有得到我的错误,我看到了结果:
before raiserror
Server: Msg 50000, Level 18, State 1, Procedure Archive_Session, Line 5
this is a raised error
before return
因此,问题是:如何摆脱SQL Server中的存储过程?将其放入
TRY/CATCH
中
以严重性运行RAISERROR时
TRY块中的值为11或更高,则
将控制权转移到关联的
挡块
参考文献:
编辑:这适用于MSSQL 2005+,但我看到您现在已经澄清您正在使用MSSQL 2000。我将把它留在这里作为参考。除非您指定20或更高的严重性,
raiserror
将不会停止执行。看
正常的解决方法是在每个错误出现后包含返回
:
if @whoops = 1
begin
raiserror('Whoops!', 18, 1)
return -1
end
您可以使用RETURN
立即停止存储过程的执行。引述自:
无条件退出查询或
程序返回是立即的,并且
完整,可在任何位置使用
退出某个过程、批处理或
语句块。声明
不执行跟随返回
出于偏执,我尝试了你的例子,它确实输出了指纹,并立即停止执行。在这里可以
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
我明白了为什么RETURN
不是从存储过程无条件返回的。我看到的错误是在编译存储过程时,而不是在执行存储过程时
考虑一个虚构的存储过程:
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.foo AS
INSERT INTO ExistingTable
EXECUTE LinkedServer.Database.dbo.SomeProcedure
即使此存储过程包含错误(可能是因为对象的列数不同,可能是表中有时间戳列,可能是存储过程不存在),您仍然可以保存它。您可以保存它,因为您正在引用链接的服务器
但当您实际执行存储过程时,SQLServer会编译它,并生成一个查询计划
我的错误不是发生在第114行,而是发生在第114行。SQL Server无法编译存储过程,这就是它失败的原因
这就是为什么RETURN
没有返回,因为它甚至还没有开始。因为没有BEGIN
和END
语句。您不应该看到打印或运行此语句的错误,只有语句完成了(或类似的内容)。这似乎有很多代码,但这是我找到的最好的方法
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
“欢迎来到加州酒店……”古?(填充使我的“Guh?”查询至少有15个字符长)哦,等等,我明白了…“你永远不能离开”。这个问题甚至需要被问到,这表明SQL有点不对劲,但再一次,它是固定在函数式语言一侧的过程方法论,那么您期望什么呢?“严重性级别从19到25只能由sysadmin固定服务器角色的成员或具有ALTER TRACE权限的用户指定。”来自MSDN@Forgotten分号:是的,所以在大多数情况下,raiserror
因其功能以无人期待的方式运行而获奖(以及金奖打字奖)+1.不是对这个问题的真正回答,而是“答案很有用”“您能想出调用return
不能无条件退出过程的任何原因吗?如果您已启动事务或有打开的游标,请小心从过程中退出。我不能-您能否发布一个完整的存储过程示例,说明当您运行它时,不会在返回时立即退出?就为了让我们有一个确切的例子来回顾这项工作,我们可以尝试一下吗?因此,如果我在TRY中调用RETURN,它是否会执行CATCH?+1 SQL Server 2000,因此这无助于回答我的问题。但对于试图处理异常的人来说,这是一种有用的技术,我真的很喜欢这样。但是叹息。。。还有一些新的东西需要学习。当然,你不应该在没有指定列的情况下编写插入代码。当然,我想在没有指定列的情况下编写插入代码。现在我必须指定它们,添加到源表的其他列将丢失。这似乎是一种更干净/更快的方式来键入。