BEGIN
CREATE TABLE #T
(
--LoginName varchar(max) NULL,
DBName varchar(max) NULL,
UserName varchar(max) NULL,
UserOrAlias varchar(max) NULL,
)
BEGIN
INSERT INTO #T EXEC sp_helplogins_test @LOGIN_NAME
SET @ERROR = @@ERROR
SET @REMARK = 'LOGIN INFORMATION 抽出エラーになる'
IF @ERROR <> 0 BEGIN GOTO ABEND_HANDLER END
END
。
。
。
ABEND_HANDLER:
BEGIN
RETURN @REMARK
ROLLBACK TRANSACTION
END
如上代码,过程sp_helplogins_test @LOGIN_NAME 返回的结果集是4列,我故意将临时表注释掉一列,然INSERT出现错误
然后通过ABEND_HANDLER:中的代码将相应的出错信息返回
可是在调试的过程中执行到INSERT的时候
SQL SERVER直接报出列数不匹配的错误信息,根本没有走ABEND_HANDLER:中的代码,请问这是为什么呢,如果想获得相应的错误信息,应该怎么写
SQL中的错误处理
--下面演示了SQL错误处理的脆弱性
--邹建--演示1
--测试的存储过程1
create proc p1
as
print 12/0
if @@error<>0
print '发生错误1'select * from newid()
if @@error<>0
print '发生错误2'
go--调用
exec p1
go--删除测试
drop proc p1/*--测试结果服务器: 消息 8134,级别 16,状态 1,过程 p1,行 6
遇到被零除错误。
发生错误1
服务器: 消息 208,级别 16,状态 1,过程 p1,行 10
对象名 'newid' 无效。--*/
/*--结论1:错误1,不是严重的错误,所以SQL会执行下去
错误2,属于严重的错误,所以SQL没有执行下去,因为没有第二个print的结果--*/--演示2,存储过程嵌套调用中的错误--测试的存储过程1
create proc p1
as
print 12/0
if @@error<>0
print '发生错误1'select * from newid()
if @@error<>0
print '发生错误2'
go--测试的存储过程2
create proc p2
as
exec p1if @@error<>0
print '调用 存储过程1 异常结束'
else
print '调用 存储过程1 正常结束'
go--调用
exec p2
go--删除测试
drop proc p1,p2/*--测试结果服务器: 消息 8134,级别 16,状态 1,过程 p1,行 8
遇到被零除错误。
发生错误1
服务器: 消息 208,级别 16,状态 1,过程 p1,行 12
对象名 'newid' 无效。
调用 存储过程1 异常结束
--*/
/*--结论2:被调用的存储过程发生严重错误时,调用它的存储过程可以捕获错误,并可以继续执行下去
--*/--演示3,更严重的错误,无法用 set xact_abort on 来自动回滚事务
set xact_abort on --我们希望能自动回滚事务
begin tran
create table #t(id int)
insert #t select 1
select * from newid()
commit tran
goselect * from #t
rollback tran
/*--测试结果
(所影响的行数为 1 行)服务器: 消息 208,级别 16,状态 1,行 5
对象名 'newid' 无效。id
-----------
1(所影响的行数为 1 行)
--*//*--结论3:我们希望 set xact_abort on 可以实现出错时自动回滚事务
但结果令我们希望,出错时,事务并没有被回滚
因为我们查询到了#t的结果,而且最后的回滚语句也并没有报错
--*/