游标的行为不一致

时间:2014-02-19 02:09:18

标签: mysql sql function cursor procedure

我有一张'dia'表

table: dia

我有这个功能:

 create table log(
      cont int
 );

 delimiter //
 CREATE FUNCTION teste (calendario INT, data_selecionada DATE)
      RETURNS INT
 BEGIN

 DECLARE corrente INT DEFAULT 0;
 DECLARE data_inicio DATE DEFAULT NULL;
 DECLARE inicio INT DEFAULT 0;
 DECLARE maior_corrente INT DEFAULT 0;
 DECLARE existe_mais_linhas INT DEFAULT 0;
 DECLARE dia_atual DATE;
 DECLARE dia_anterior DATE DEFAULT NULL;
 DECLARE semana_atual INT DEFAULT -1;
 DECLARE semana_anterior INT DEFAULT -1;
 DECLARE total_vidas INT DEFAULT 0;
 DECLARE vidas INT DEFAULT 0;

 DECLARE meuCursor CURSOR FOR SELECT data, YEARWEEK(data), inicio_corrente FROM dia WHERE data >= data_selecionada and tem_corrente = 1 and calendario_id = calendario order by data asc;

 DECLARE CONTINUE HANDLER FOR NOT FOUND SET existe_mais_linhas=1;

 SELECT data into data_inicio FROM dia WHERE tem_corrente = 1 and inicio_corrente = 1 and data < data_selecionada order by data desc limit 1;

 OPEN meuCursor;

 meuLoop: LOOP
 FETCH meuCursor INTO dia_atual, semana_atual, inicio;
      insert into log (cont) values (1);

      IF existe_mais_linhas = 1 THEN
           LEAVE meuLoop;
      END IF;

 END LOOP meuLoop;

 CLOSE meuCursor;
 RETURN 0;

 END//
 delimiter ;

当我调用该函数时:

 SELECT teste( 1,  '2014-01-26' )

表日志只包含一行......这是错误的,因为光标必须访问所有九行...但是,如果我删除该行:

 SELECT data into data_inicio FROM dia WHERE tem_corrente = 1 and inicio_corrente = 1 and data < data_selecionada order by data desc limit 1;"

(我觉得这条线无关紧要)。但是现在,当我调用相同的函数时,表日志包含九行......该行如何影响循环?

1 个答案:

答案 0 :(得分:1)

第一个查询返回NO数据..所以变量已经是SET并且程序流继续..因为你在取消设置之前在循环中引用它...而不是像你期望的那样检查游标的数据。 !!

 SELECT data into data_inicio FROM dia WHERE tem_corrente = 1 and inicio_corrente = 1 and data < data_selecionada order by data desc limit 1;


 IF existe_mais_linhas = 1 THEN
    SET existe_mais_linhas = 0;-- unset it using SET..
  END IF;

 OPEN meuCursor;

 meuLoop: LOOP
 FETCH meuCursor INTO dia_atual, semana_atual, inicio;

      IF existe_mais_linhas = 1 THEN
           LEAVE meuLoop;
      END IF;

       -- Move the insert after checking it!

      insert into log (cont) values (1);

 END LOOP meuLoop;