powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Курсор в курсоре
6 сообщений из 6, страница 1 из 1
Курсор в курсоре
    #39084687
Nathaly
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Как правильно написать один курсов внутри другого, чтобы после обработки внутреннего курсора происходил переход на следующую запись внешнего курсора, а не прекращалась обработка?
Вот такой код отрабатывает не корректно, обрабатывается только первая запись внешнего курсора cur1, затем отрабатывает внутренний курсор cur2, после чего не происходит переход к следующей записи cur1 и обработка заканчивается
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
DROP TABLE IF EXISTS otl;
create table otl (
qty numeric(11,2),
d datetime,
deal numeric (9,0));

DROP  PROCEDURE IF EXISTS demo;
CREATE PROCEDURE demo()
BEGIN
  DECLARE done, done2 INT DEFAULT FALSE;
  declare vqty numeric(11,2);
  declare vd datetime;
  declare vdeal numeric (9,0)  ;
  
  DECLARE cur1 CURSOR FOR SELECT deal, sum(qty) FROM otl having sum(qty)>0;
  DECLARE cur2 CURSOR FOR SELECT d FROM otl where deal = vdeal;
  
  OPEN cur1;
  SET done = 0;
  FETCH cur1 INTO  vDeal, vQty ;
  WHILE NOT done DO 
  
        OPEN cur2;
        SET done2 = 0;
        FETCH cur2 INTO  vd ;
        WHILE NOT done2 DO 
          IF vd<now() THEN
            /*действие 1 и выход из этого курсора*/
            SET done2 = 1;              
          ELSE
            /*действие 2*/
            SET done2 = 0;   
          END IF;
        FETCH cur2 INTO  vd ;
        END WHILE;
        CLOSE cur2;
                     
      SET done = 0;
      FETCH cur1 INTO  vDeal, vQty ;
  END WHILE;
  CLOSE cur1;        
END;
...
Рейтинг: 0 / 0
Курсор в курсоре
    #39084705
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну начать с того, что переменная done у тебя ВСЕГДА равна нулю.
Далее - если ты используешь прямое присвоение переменной типа INT, то фигли ты инициируешь и потом анализируешь как булеву? используй именно целые значения и прямое сравнение.
...
Рейтинг: 0 / 0
Курсор в курсоре
    #39084723
Nathaly
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Akina,
если я напишу
Код: sql
1.
DECLARE done, done2 INT DEFAULT 0;


то легче от этого не станет.
Вопрос в том как правильно написать, чтобы не вылетало сразу из обоих курсоров. Т.е. когда во внутреннем заканчиваются данные, то SQLSTATE: 02000 и происходит выход сразу из обоих курсоров, а не только из внутреннего.
...
Рейтинг: 0 / 0
Курсор в курсоре
    #39084741
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NathalyТ.е. когда во внутреннем заканчиваются данные, то SQLSTATE: 02000 и происходит выход сразу из обоих курсоров, а не только из внутреннего.
Правильно. Обработчик никак не может узнать, с каким из курсоров проблема.
Помоги ему - заведи переменную и перед фетчем пиши в неё опознавалку, откуда фетчишь. Например. Но лучше напиши правильный DECLARE CONTINUE HANDLER FOR NOT FOUND.
...
Рейтинг: 0 / 0
Курсор в курсоре
    #39084945
Nathaly
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Akina Но лучше напиши правильный DECLARE CONTINUE HANDLER FOR NOT FOUND.
Я, конечно, туплю по страшному., но ника кне помгу сообразить как правильно это написать. Следующий вариант не помогает.
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
  DECLARE done, done2 INT DEFAULT 0;
  DECLARE cur1 CURSOR FOR SELECT deal, sum(qty) FROM otl having sum(qty)>0;
  DECLARE cur2 CURSOR FOR SELECT d FROM otl where deal = vdeal;
  DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done=1;

  OPEN cur1;
  FETCH cur1 INTO  vDeal, vQty ;
  WHILE NOT done DO   
        
        OPEN cur2;
        SET done2 = 0;
        FETCH cur2 INTO  vd ;
        WHILE NOT done2 DO 
          IF vd<now() THEN
            /*действие 1 и выход из этого курсора*/
            SET done2 = 1;              
          ELSE
            /*действие 2*/
            SET done2 = 0;   
          END IF;
        FETCH cur2 INTO  vd ;
        END WHILE;
        CLOSE cur2;
        
      FETCH cur1 INTO  vDeal, vQty ;
  END WHILE;
  CLOSE cur1;        
END;



Переменную завела, перед фетчем проверяю - так работает, но не красиво. Хочется чтобы всё по уму было.
...
Рейтинг: 0 / 0
Курсор в курсоре
    #39085132
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну неправильно же. Подумай, что будет, если во внутреннем цикле ни одна из записей второго курсора не соответствует условию.
...
Рейтинг: 0 / 0
6 сообщений из 6, страница 1 из 1
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Курсор в курсоре
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]