由于项目需要,需要将之前的一个MySQL项目移值到SQL Server上面去。本人之前也只是简单应用MySQL,很少接触MySQL的存储过程,在阅读项目之前MySQL的过程是,发现了一些问题,想请教一下各位。过程如下:DELIMITER $$DROP PROCEDURE IF EXISTS `dam`.`p_delete_gauge_flow_date_all` $$
CREATE DEFINER=`root`@`%` PROCEDURE `p_delete_gauge_flow_date_all`(iCurveID  bigint)
BEGIN
  declare iCount integer;
  set autocommit = 0;
  set @iCount = 0;
  
  START TRANSACTION;
  set @iCount = @iCount + 1;
  
  delete from sys_gauge_flow_date where curve_id = iCurveID;
  delete from sys_gauge_flow where curve_id = iCurveID;
  
  select "0k" as result;
  if @iCount = 1 then
    commit;
  else
    rollback;
  end if;  
END $$DELIMITER ;
很明显这是一个事务处理的过程。我不知道是前人写的有问题,还是我的理解有问题,还请各位指证。
问题一:
START TRANSACTION;
set @iCount = @iCount + 1;不管事务中的操作会不会出错,@iCount应该都会是1,也就是说靠判定if @iCount = 1,永远也不会执行rollback
问题二:select "0k" as result;这个返回值,我认为应该放到commit后面,同时在rollback后面加上 select "ERR" as result;问题三:
虽然这是一个事务处理过程,但我认为就算是两条delete语句中的任何一条发生问题,也不会发生rollback。因为对于sql语句来说,出错的情况下,只能采用declare handler来捕获,而目前的过程是无法捕获错误的,根本无法实现rollback。问题四:
如果采用了START TRANSACTION;  是不是意味着 set autocommit = 0; 这句话为0或是为1都不会产生影响。以上四点是我的理解,不知道对与不对,还请高人指证

解决方案 »

  1.   

    1 2 3同意  
    4  start transaction就是set autocommit=0
      

  2.   

    那如果把  set @iCount = @iCount + 1;放到所有的sql语句之后,if @iCount = 1 then  之前,是不是就有点作用
      

  3.   

    你可以 DECLARE CONTINUE HANDLER FOR SQLEXCEPTION 来捕捉错误。
      

  4.   


    这里的Continue,指什么,假如捕捉到错误后,什么也不做,continue就是继续往下执行的意思
    是不是这样理解,有三条sql语句,1正确,2出错了,然后因为Continue的缘故,是不是会接下来执行第三条sql语句
    因为之前的写mysql的过程的人,大量的使用了set @iCount = @iCount + 1;这种方法来处理事务,按照你们的观点,那他就是大错特错了,他这样做,有什么意义没有?
      

  5.   

    数据库中有66个过程,差不多都采用的是
    START TRANSACTION;
    set @iCount = @iCount + 1;
    。。
    if @iCount = 1 then
    commit;
    else
    rollback;
    end if;
    这种方式处理的,那按你的意思,这种方法就是错误的,根本就起不到作用。但写这些过程的人,感觉水平还不低,我总觉得不会犯这种错误吧,因为我是昨天才研究了一下MySQL的过程,所以不敢枉下结论
      

  6.   

    这是我理解后,改写的过程,还请各位高人帮我看看,我这样写是不是就正确的DELIMITER $$DROP PROCEDURE IF EXISTS `dam`.`p_delete_gauge_flow_date_all` $$
    CREATE DEFINER=`root`@`%` PROCEDURE `p_delete_gauge_flow_date_all`(iCurveID  bigint)
    BEGIN
      declare exit handler for SQLEXCEPTION begin
        rollback;
        select "ERR" as result; 
       end;
      
      START TRANSACTION;
      
      delete from sys_gauge_flow_date where curve_id = iCurveID;
      delete from sys_gauge_flow where curve_id = iCurveID;
      
     
      commit;
      select "0k" as result; 
    END $$DELIMITER ;