PRINT ''After INSERT.''
END TRY
BEGIN CATCH
PRINT ''INSERT failed.''
/* perform corrective activity */
END CATCH
当您首次运行该代码时,应当获得输出“After INSERT”。当您第二次运行它时,应当获得输出“INSERT Failed”。
如果 TRY 块中的代码没有任何错误地完成,则控制被传递给相应的 CATCH 块后面的第一个语句。当 TRY 块中的语句失败时,控制被传递给相应的 CATCH 块中的第一个语句。请注意,如果错误被 CATCH 块捕获,则它不会返回到调用应用程序。如果您还希望应用程序获得错误信息,则必须自己将该信息提供给应用程序(例如,使用 RAISERROR 或作为查询的结果集)。所有错误信息都借助于四个新的函数在 CATCH 块中提供给您:ERROR_NUMBER()、ERROR_MESSAGE()、ERROR_SEVERITY() 和 ERROR_STATE()。这些函数可以在 CATCH 块中您喜欢的任何位置多次查询,并且它们的值保持不变。这与除 DECLARE 以外还受到任何语句影响的 @@error 函数(因此必须在 CATCH 块的第一个语句中查询它)相反。ERROR_NUMBER() 可以用作 @@error 的替代函数,而其他三个函数则完全按照由错误生成的样子向您提供该信息的其余部分。此类信息在低于 SQL Server 2005 的 SQL Server 版本中无法获得。
如果在批处理或例程(存储过程、触发器、用户定义的函数、动态代码)中生成了未处理的错误,并且某个较高级别的代码在 TRY 块内部调用了该批处理或例程,则控制被传递给该较高级别的相应 CATCH 块。如果该较高级别没有在 TRY 块内调用该内部级别,则 SQL Server 将继续在调用堆栈中的较高级别中查找 TRY 块,并且会将控制传递给找到的第一个 TRYCATCH 结构的 CATCH 块。如果未找到,则将错误返回给调用应用程序。
作为一个更详细的示例,以下代码根据导致失败的错误的类型做出不同的反应,并且输出消息以表明代码的哪些部分已经被激活:
PRINT ''Before TRYCATCH block.''
BEGIN TRY
PRINT '' Entering TRY block.''
INSERT INTO Employees(empid, empname, mgrid) VALUES(2, ''Emp2'', 1)
PRINT '' After INSERT.''
PRINT '' Exiting TRY block.''
END TRY
BEGIN CATCH
PRINT '' Entering CATCH block.''
IF ERROR_NUMBER() = 2627
BEGIN
PRINT '' Handling PK violation''
END
ELSE IF ERROR_NUMBER() = 547
BEGIN
PRINT '' Handling CHECK/FK constraint violation''
END
ELSE IF ERROR_NUMBER() = 515
BEGIN
PRINT '' Handling NULL violation''
END
ELSE IF ERROR_NUMBER() = 245
BEGIN
PRINT '' Handling conversion error''
END
ELSE
BEGIN
PRINT '' Handling unknown error''
END
PRINT '' Error Number: '' + CAST(ERROR_NUMBER() AS VARCHAR(10))
PRINT '' Error Message: '' + ERROR_MESSAGE()
PRINT '' Error Severity: '' + CAST(ERROR_SEVERITY() AS VARCHAR(10))
PRINT '' Error State : '' + CAST(ERROR_STATE() AS VARCHAR(10))
PRINT '' Exiting CATCH block.''
END CATCH
PRINT ''After TRYCATCH block.''
请注意,ERROR_NUMBER() 函数在 CATCH 块中被多次调用,并且它总是返回导致控制传递给该 CATCH 块的错误的编号。该代码将雇员 2 作为先前插入的雇员 1 的下属插入,并且在首次运行时应当没有任何错误地完成,并生成以下输出:
Before TRYCATCH block.
Entering TRY block.
After INSERT.
Exiting TRY block.
After TRYCATCH block.
请注意,CATCH 块被跳过。第二次运行该代码时,应当生成以下输出:
Before TRYCATCH block.
Entering TRY block.
Entering CATCH block.
Handling PK violation
Error Number: 2627
Error Message: Violation of PRIMARY KEY constraint ''PK_Employees''.
Cannot insert duplicate key in object ''Employee