日期:2014-05-17  浏览次数:20695 次

请问怎样捕捉到存储过程里面的错误?
use northwind

create procedure test as

  begin tran tran_test
   
  select RegionId into #a from region

  insert into #a(RegionId)
  select m.RegionId from #a
  if @@error<>0 rollback tran tran_test

  commit tran tran_test


上面写了个存储过程,然后里面有个错误,就是 m.RegionId,m是错误的,没有别名的,
但我调用它时:
exec test

却捕捉不到错误,要怎样才能获取到 错误,然后回滚事务呢?
我无法检测到是否有错误



------解决方案--------------------
用try catch
------解决方案--------------------
SQL code
CREATE PROCEDURE test
AS 
BEGIN TRY 
      BEGIN TRAN tran_test
    
      SELECT  RegionId
      INTO    #a
      FROM    region

      INSERT  INTO #a ( RegionId )
              SELECT  m.RegionId
              FROM    #a

      COMMIT TRAN tran_test
END TRY 
BEGIN CATCH
      IF XACT_STATE() <> 0 
         ROLLBACK TRANSACTION ;
      DECLARE @error_number INT ,
              @error_line INT ,
              @error_message NVARCHAR(2040) ; 
      SELECT  @error_number = ERROR_NUMBER(), @error_message = ERROR_MESSAGE(), @error_line = ERROR_LINE() ; 
      RAISERROR( 
        N'%s', 
        @error_number, 1, 
        @error_message,@error_line 
        ) ; 
END CATCH

------解决方案--------------------
SQL code


use northwind

create procedure test as
begin

  begin tran  
  begin try
      select RegionId into #a from region

      insert into #a(RegionId)
      select m.RegionId from #a
      
      commit tran 
  end try
  begin catch
    select error_number() as error_number ,
    error_message() as error_message,
    error_state() as error_state,
    error_severity() as error_severity
    rollback tran
  end catch
  

end

------解决方案--------------------
http://blog.csdn.net/htl258/article/details/4125446
------解决方案--------------------
begin try
begin transaction tran1
update。。。
insert 。。。
commit transaction tran1
end try
begin catch
if @@trancount>0
rollback tran1
enc catch
------解决方案--------------------
@@error 需要每语句的记录

比如你这个语句 如果第一个错了

那么在第二个语句后面 @@error是得不到错误号的

------解决方案--------------------
2000没有这个语法
------解决方案--------------------
用RAISERROR,你前台可以扑捉到存储过程或触发器的错误。
SQL code
RAISERROR
返回用户定义的错误信息并设系统标志,记录发生错误。通过使用 RAISERROR 语句,客户端可以从 sysmessages 表中检索条目,或者使用用户指定的严重度和状态信息动态地生成一条消息。这条消息在定义后就作为服务器错误信息返回给客户端。

语法
RAISERROR ( { msg_id | msg_str } { , severity , state }
    [ , argument [ ,...n ] ] )
    [ WITH option [ ,...n ] ]

参数
msg_id

存储于 sysmessages 表中的用户定义的错误信息。用户定义错误信息的错误号应大于 50,000。由特殊消息产生的错误是第 50,000 号。

msg_str

是一条特殊消息,其格式与 C 语言中使用的 PRINTF 格式样式相似。此错误信息最多可包含 400 个字符。如果该信息包含的字符超过 400 个,则只能显示前 397 个并将添加一个省略号以表示该信息已被截断。所有特定消息的标准消息 ID 是 14,000。

msg_str 支持下面的格式:

% [[flag] [width] [precision] [{h | l}]] type

可在 msg_str 中使用的参数包括:

flag

用于确定用户定义的错误信息的间距和对齐的代码。

代码 前缀或对齐 描述 
-(减) 左对齐 在给定字段宽度内左对齐结果。 
+(加) +(加)或 -(减)前缀 如果输出值为带符号类型,则在输出值的前面加上加号(+)或减号(-)。 
0(零) 零填充 如果宽度的前面有 0,则添加零直到满足最小宽度。若出现 0 和 -,将忽略 0。若使用整型格式(i, u, x, X, o, d)指定 0,则忽略 0。 
#(数字) 对 x 或 X 的十六进制类型使用 0x 前缀 当使用 o、x 或 X 格式时,# 标志在任何非零值的前面分别加上 0、0x 或 0X。当 d、i 或 u 的前面有 # 标记时,将忽略该标记。 
' '(空格) 空格填充 如果输出值带符号且为正,则在该值前加空格。如果包含在加号(+)标记中,则忽略该标记。 


width

定义最小宽度的整数。星号 (*) 允许 precision 确定宽度。

precision

是输出字段最多输出的字符数,或为整数值输出的最小小数位数。星号 (*) 允许 argument 确定精度。

{h | l} type

与字符类型 d、i、o、x、X 或 u 一起使用,用于创建 short int (h) 或 long int (l) 类型的值。

字符类型 表示 
d 或 I 带符号的整数 
o 不带符号的八进制数 
p 指针型 
s String 
u 不带符号的整数 
x 或 X 不带符号的十六进制数 




说明  不支持 float、双精度和单精度字符类型。


severity

用户定义的与消息关联的严重级别。用户可以使用从 0 到 18 之间的严重级别。19 到 25 之间的严重级别只能由 s