我描述一下现在出现的问题。
存储过程 A,B.
A大致内容如下:DECLARE EXIT HANDLER FOR SQLEXCEPTION ROLLBACK; 
start transaction; 

调用存储过程B

commit;
B存储过程比较简单就是对一个传入的长字符串进行截取,然后在插入数据库。(不包含start transaction;和commit;)
在一般情况下,无论是A还是B中出现异常都能进行回滚到存储过程A执行前的状态。
但是我最近发现存储过程B传入字符串为“”时,无法回滚。存储过程B的代码如下:
declare ilen int;
declare iTollen int;declare dSevMA double;
declare dSevOA double;

Set ilen = locate('|',strSevHowToPay)-1;
Set iTollen = Length(strSevHowToPay) - ilen -1;
Set dSevMA = left(strSevHowToPay,ilen);
Set strSevHowToPay = substring(strSevHowToPay,iLen+2,iTollen);Set ilen = locate('|',strSevHowToPay)-1;
Set iTollen = Length(strSevHowToPay) - ilen -1;
Set dSevOA = left(strSevHowToPay,ilen);
Set strSevHowToPay = substring(strSevHowToPay,iLen+2,iTollen);
strSevHowToPay为传入的长字符串,当它为“”时,出现的异常。
存储过程A中DECLARE EXIT HANDLER FOR SQLEXCEPTION ROLLBACK; 无法进行回滚。这是怎么回事?
难道存储过程A中DECLARE EXIT HANDLER FOR SQLEXCEPTION ROLLBACK; 无法对存储过程B中出现的异常进行回滚?是否需要在存储过程B中添加DECLARE EXIT HANDLER FOR SQLEXCEPTION ROLLBACK。

解决方案 »

  1.   

    我现在在存储过程中添加了DECLARE EXIT HANDLER FOR SQLEXCEPTION ROLLBACK。
    但是无法对在调用存储过程B之前的存储过程A所执行的语句进行回滚如果想在意在存储过程中进行回滚应当如何处理
    ?、
      

  2.   

    你的数据库表必须是事务型!,不是事务型的,默认还是一条一条插入,表类型改为InnoDB试试
      

  3.   

    表类型是InnoDB的 我现在是在存储过程A执行失败后在,执行RollBack进行回滚的 但感觉不在一个事物,怕存在隐患
      

  4.   

    表类型必须是InnoDB或者NDB,然后把自动提交置为0
      

  5.   

    已经将自动提交设为0了。可是还是不行。
    我将我自己的测试例子发上来,大家能不能帮我看看表T1
        ID              Name
    --------------- -------------
        01               Lee存储过程Proc1
    BEGIN
    #Routine body goes here...
    DECLARE EXIT HANDLER FOR SQLEXCEPTION ROLLBACK;  set   autocommit   =   0; start transaction; 
    delete from t1;
    insert into  t1 values('02','1ss');

    call Proc2(A); update t1 Set name = '3ss';

    commit;
    END
    存储过程Proc2
    BEGIN
    #Routine body goes here...
    declare ilen int;
    declare iTollen int;
    declare dSevMA double;
    Set ilen = locate('|','')-1;
    Set iTollen = Length('') - ilen -1;
    Set dSevMA = left('',ilen);
    update t1 Set name = '12';
    END
      

  6.   

    在执行
    Set @a = 0;
    Call Proc1(@a);后会提示Proc2 中存在错误。
    同时数据库中T1表格没有发生变化。但是如果在执行其他语句。T1表中值就会变为
        ID              Name 
    --------------- ------------- 
        02              1ss
    就是说 对于Proc2中发生的错误,Proc1中无法进行回滚。这样应当如何处理比较好?我现在对于这种情况,是在提示后执行存储过程Proc1失败后,马上执行RollBack!但是这样就不在一个存储过程中,是否有影响?
     
      

  7.   

    这个问题,我以前好象有碰过,我的解决方式是用begin 。。end嵌套start transaction;
    delete from t1;
    insert into  t1 values('02','1ss');nextproc:begin
       DECLARE IS_ERROR INTEGER DEFAULT 0;
       DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET IS_ERROR=1;
       call Proc2(A);
       if is_error=1
          rollback;
       end if;
    end nextproc;

    update t1 Set name = '3ss';commit;
    END 
      

  8.   

    很感谢楼上的回答我测试过了 
    还是不行。  同时:我将Proc2中的代码转移到Proc1中:
    BEGIN
    #Routine body goes here...

            declare ilen int;
    declare iTollen int;
    declare dSevMA double; DECLARE EXIT HANDLER FOR SQLEXCEPTION ROLLBACK;  set   autocommit   =   0; start transaction; 
    delete from t1;
    insert into  t1 values('2','D');

    nextproc:begin
            DECLARE IS_ERROR INTEGER DEFAULT 0;
            DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET IS_ERROR=1;
    Set ilen = locate('|','')-1;
    Set iTollen = Length('') - ilen -1;
    Set dSevMA = left('',ilen);        if is_error=1 then
           rollback;
        end if;
    end nextproc;
    update t1 Set name = '3';

    commit;
    END
    感觉问题的关键是SQLEXCEPTION 不包含这个存储过程中发生的错误!
      

  9.   

    上面那个Proc1还是存在相同的问题
    说明出问题不在于是否嵌套调用存储过程关键是SQLEXCEPTION 不包含这个存储过程中发生的错误!
    不能对发生的错误进行处理
      

  10.   

    有点糊涂了,CREATE PROCEDURE `new_proc`()
        NOT DETERMINISTIC
        SQL SECURITY DEFINER
        COMMENT ''
    BEGIN
         declare ilen int;
         declare iTollen int;     declare dSevMA double;
         Set ilen = locate('|','')-1;
         Set iTollen = Length('') - ilen -1;
         Set dSevMA = left('',ilen);
    END;call new_proc() -- 是成功的, 怎么会产生异常呢?还是你要让它抛出异常?
      

  11.   

    Set dSevMA = left('',ilen); 
    我这边提示这句有错!
    数据截断出错了