@@ERROR用法
@@ERROR 最近的语句错误码,局限于DML语句和select语句,如果执行他们出现错误,则返回一个不等于0的错误码,如果没有出错,则返回0。通常使用它来判断语句有没有执行成功。
在 Transact-SQL 中两种获取错误信息的方式
(1)在 TRY...CATCH 构造的 CATCH 块的作用域内,使用以下系统函数:
- ERROR_LINE(),返回出现错误的行号。
- ERROR_MESSAGE(),返回将返回给应用程序的消息文本。该文本包括为所有可替换参数提供的值,如长度、对象名或时间。
- ERROR_NUMBER() 返回错误号。
- ERROR_PROCEDURE(),返回出现错误的存储过程或触发器的名称。如果在存储过程或触发器中未出现错误,该函数返回 NULL。
- ERROR_SEVERITY() 返回严重性。
- ERROR_STATE(),返回状态。
- (下面所使用“系统函数”特指上面所列出的几个系统函数)
(2)在执行任何 Transact-SQL 语句之后,立即使用 @@ERROR 函数测试错误并检索错误号。
TRY...CATCH 的使用
Transact-SQL 中的TRY...CATCH与 C# 语言中的try….catch 功能类似。
在T-SQL 中使用TRY...CATCH时注意一下几点:
(1)TRY..CATCH 构造中使用的系统函数,仅在 CATCH 块的作用域内时,系统函数才返回错误信息。在 CATCH 块的作用域外时,返回 NULL。
(2)只要是在 CATCH 块的作用域内运行,系统函数即使被引用多次也将返回相同的错误信息。
(3)CATCH 块必须紧跟 在TRY 块之后,其间不能插入任何SQL语句。
(4)每个 TRY...CATCH 构造都必须位于一个批处理、存储过程或触发器中。(而不能将 TRY 块放置在一个批处理中,将关联的CATCH 块放置在另一个批处理中)
(5)TRY…CATCH 构造可以嵌套,当嵌套的 TRY 块中出现错误时,程序控制将传递到与嵌套的 TRY 块关联的 CATCH 块。
(6)可以在 TRY 块或 CATCH 块内使用 GOTO。GOTO 还可用于退出 TRY 块或 CATCH 块;但是,无法使用 GOTO 进入 TRY 块或 CATCH 块。
(7)严重性为 10 或更低的错误被视为警告或信息性消息,TRY...CATCH 块不处理此类错误。
(8)TRY...CATCH 块不处理导致数据库引擎关闭连接的严重性为 20 或更高的错误。(只要连接不关闭,TRY...CATCH 就会处理严重性为 20 或更高的错误)
(9)编译错误和语句级重新编译错误,是与TRY...CATCH 构造在同一执行级别发生的错误,TRY...CATCH 将不处理。
(10)在 TRY...CATCH 构造中,事务可以进入一种状态:事务保持打开但无法提交。
(CATCH 块中的代码可以通过使用 XACT_STATE 函数来测试事务的状态。如果会话中包含无法提交的事务,XACT_STATE 将返回 -1。如果 XACT_STATE 返回 -1,则 CATCH 块将不能执行写日志的任何操作)
(11)TRY...CATCH 可用于处理死锁。CATCH 块可以捕获 1205 死锁牺牲品错误,并且事务可以回滚,直至线程解锁。
(12)即使批处理位于 TRY...CATCH 构造的作用域内,关注消息仍将终止该批处理。分布式事务失败时,Microsoft 分布式事务处理协调器 (MS DTC) 将发送关注消息。MS DTC 用于管理分布式事务。
@@ERROR 函数的使用
如果上一个 Transact-SQL 语句执行成功,@@ERROR 系统函数将返回 0;如果该语句生成错误,@@ERROR 将返回错误号。每个 Transact-SQL 语句完成时,@@ERROR 的值都会更改。
因为每个 Transact-SQL 语句完成时,@@ERROR 都会获得一个新值,可以用以下两种方法之一处理 @@ERROR:
- (1)在 Transact-SQL 语句完成后,立即测试或使用 @@ERROR。
- (2)在 Transact-SQL 语句完成后,立即将 @@ERROR 保存到整数变量中。此变量的值可供以后使用。
- 在T-SQL 中使用@@ERROR 时注意一下几点:
(1)@@ERROR 仅在生成错误的 Transact-SQL 语句之后,立即返回错误信息。
- (2)如果生成错误的语句在 TRY 块中,则 @@ERROR 值必须在相关的 CATCH 块的第一条语句中进行测试和检索。
- 如果生成错误的语句不在 TRY 块中,则 @@ERROR 值必须在生成错误的语句之后立即在语句中进行测试和检索。
(3)在 CATCH 块的作用域外,@@ERROR 中的错误号是有关 Transact-SQL 代码内错误的唯一可用信息。
(4)在条件性语句(如if)中使用@@ERROR函数时,在(if或else中)对@@ERROR 的引用将不检索 @@ERROR 信息,而是将@@ERROR 重置。
(5)如果要在运行语句之后同时引用 @@ERROR 和 @@ROWCOUNT,则必须在同一语句中引用它们。@@ERROR 和 @@ROWCOUNT 都可以使用每条 Transact-SQL 语句进行重置。
(6)@@ERROR 仅由错误产生,而不由警告产生;批处理、存储过程和触发器不能使用 @@ERROR 检测任何已发生的警告。