use northwindcreate 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却捕捉不到错误,要怎样才能获取到 错误,然后回滚事务呢?
我无法检测到是否有错误

解决方案 »

  1.   

    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 
      

  2.   

    use northwindcreate 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
      

  3.   

    http://blog.csdn.net/htl258/article/details/4125446
      

  4.   

    begin try
       begin transaction tran1
         update
         insert 
       commit transaction tran1
    end try
    begin catch
    if @@trancount>0
    rollback tran1
    enc catch
      

  5.   

    @@error 需要每语句的记录比如你这个语句 如果第一个错了那么在第二个语句后面 @@error是得不到错误号的
      

  6.   

    晕,我是用sql2000,没有try catch,不是第一句错,而是 第二句错,第二句我就检查了,但检查不到错误
      

  7.   

    用RAISERROR,你前台可以扑捉到存储过程或触发器的错误。
    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 之间的严重级别只能由 sysadmin 固定服务器角色成员使用。若要使用 19 到 25 之间的严重级别,必须选择 WITH LOG 选项。注意  20 到 25 之间的严重级别被认为是致命的。如果遇到致命的严重级别,客户端连接将在收到消息后终止,并将错误记入错误日志和应用程序日志。
    state从 1 到 127 的任意整数,表示有关错误调用状态的信息。state 的负值默认为 1。argument是用于取代在 msg_str 中定义的变量或取代对应于 msg_id 的消息的参数。可以有 0 或更多的替代参数;然而,替代参数的总数不能超过 20 个。每个替代参数可以是局部变量或这些任意数据类型:int1、int2、int4、char、varchar、binary 或 varbinary。不支持其它数据类型。option错误的自定义选项。option 可以是以下值之一:值 描述 
    LOG 将错误记入服务器错误日志和应用程序日志。记入服务器错误日志的错误目前被限定为最多 440 字节。 
    NOWAIT 将消息立即发送给客户端。 
    SETERROR 将 @@ERROR 的值设置为 msg_id 或 50000,与严重级别无关。 
    注释
    如果使用 sysmessages 错误并且是使用前面显示的 msg_str 格式创建的消息,则将给所提供的 msg_id 的消息传递提供的参数(argument1、argument2 等等)。当使用 RAISERROR 创建和返回用户定义的错误信息时,使用 sp_addmessage 添加用户定义的错误信息,使用 sp_dropmessage 删除用户定义的错误信息。当出现错误时,错误号将放在 @@ERROR 函数中,该函数存储最新生成的错误号。对于严重级别为 1 到 10 的消息,@@ERROR 的默认设置为0。示例
    A. 创建特定消息
    下例显示可能出现的两种错误。第一种错误很简单,生成的是静态消息。第二种错误则是在尝试修改的基础上动态生成的。CREATE TRIGGER employee_insupd
    ON employee
    FOR INSERT, UPDATE
    AS
    /* Get the range of level for this job type from the jobs table. */
    DECLARE @@MIN_LVL tinyint,
       @@MAX_LVL tinyint,
       @@EMP_LVL tinyint,
       @@JOB_ID smallint
    SELECT @@MIN_LVl = min_lvl, 
       @@MAX_LV = max_lvl, 
       @@ EMP_LVL = i.job_lvl,
       @@JOB_ID = i.job_id
    FROM employee e, jobs j, inserted i 
    WHERE e.emp_id = i.emp_id AND i.job_id = j.job_id
    IF (@@JOB_ID = 1) and (@@EMP_lVl <> 10) 
    BEGIN
       RAISERROR ('Job id 1 expects the default level of 10.', 16, 1)
       ROLLBACK TRANSACTION
    END
    ELSE
    IF NOT @@ EMP_LVL BETWEEN @@MIN_LVL AND @@MAX_LVL)
    BEGIN
       RAISERROR ('The level for job_id:%d should be between %d and %d.',
          16, 1, @@JOB_ID, @@MIN_LVL, @@MAX_LVL)
       ROLLBACK TRANSACTION
    ENDB. 在 sysmessages 中创建特殊消息
    下例显示如何通过执行 employee_insupd 触发器获得与 RAISERROR 相同的效果,而 RAISERROR 使用给存储在 sysmessages 表中的消息传递参数的方法。该消息通过 sp_addmessage 系统存储过程,以消息号 50005 被添加到 sysmessages 表中。说明  下例仅供举例说明。
    RAISERROR (50005, 16, 1, @@JOB_ID, @@MIN_LVL, @@MAX_LVL)
    或你在存储过程中返回一个输出参数,根据这个参数判断存储过程是否执行成果;在delphi里根据参数值判断是否触发异常
    http://topic.csdn.net/u/20090402/14/033cfc65-7eab-4588-9634-622d9ef56b16.html