日期:2014-05-16  浏览次数:20754 次

存储过程的问题
由于项目需要,需要将之前的一个MySQL项目移值到SQL Server上面去。本人之前也只是简单应用MySQL,很少接触MySQL的存储过程,在阅读项目之前MySQL的过程是,发现了一些问题,想请教一下各位。过程如下:
SQL code

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 2 3同意
4 start transaction就是set autocommit=0
------解决方案--------------------
你可以 DECLARE CONTINUE HANDLER FOR SQLEXCEPTION 来捕捉错误。