DECLARE done1 INT DEFAULT 0;
DECLARE done2 INT DEFAULT 0;
DECLARE cur1 CURSOR FOR SELECT bla-bla-bla FROM table_from;
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done1 = 1;
DECLARE param INT;
DECLARE cur2 CURSOR FOR SELECT bla-bla-bla FROM table2 where
id=param;
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done2 = 1;
mysql5 PROCEDURE CURSOR
Пишу процедуру экспорта новостей из одной БД в другую.
Код:
DECLARE done1 INT DEFAULT 0;
DECLARE done2 INT DEFAULT 0;
DECLARE cur1 CURSOR FOR SELECT bla-bla-bla FROM table_from;
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done1 = 1;
DELETE FROM `debug`;
insert into debug (`text`) values('begin import_news');
insert into debug (`text`) values('OPEN CURSOR cur1');
OPEN cur1;
REPEAT
FETCH cur1 INTO bla-bla-bla;
IF NOT done1 THEN
-- тут переносим одну запись в другую
/*
DECLARE cur2 CURSOR FOR select bla-bla FROM comment_table_from;
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done2 = 1;
OPEN cur2;
REPEAT
FETCH cur2 INTO bla-bla
UNTIL done2 END REPEAT;
SET done2=0;
*/
END IF;
UNTIL done1 END REPEAT;
insert into debug (`text`) values('CLOSE CURSOR');
CLOSE cur1;
DECLARE done2 INT DEFAULT 0;
DECLARE cur1 CURSOR FOR SELECT bla-bla-bla FROM table_from;
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done1 = 1;
DELETE FROM `debug`;
insert into debug (`text`) values('begin import_news');
insert into debug (`text`) values('OPEN CURSOR cur1');
OPEN cur1;
REPEAT
FETCH cur1 INTO bla-bla-bla;
IF NOT done1 THEN
-- тут переносим одну запись в другую
/*
DECLARE cur2 CURSOR FOR select bla-bla FROM comment_table_from;
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done2 = 1;
OPEN cur2;
REPEAT
FETCH cur2 INTO bla-bla
UNTIL done2 END REPEAT;
SET done2=0;
*/
END IF;
UNTIL done1 END REPEAT;
insert into debug (`text`) values('CLOSE CURSOR');
CLOSE cur1;
Проблема в том, что вместе с новостю нужно перенести комменты к ней. Я хотел сделать вложенный цикл с курсором, но БД не дает определять переменные в процедуре после использования каких-либо операторов. Следовательно - я не могу определить курсор для таблицы с комментами в главном цикле обхода таблицы с новостями.
Как решить проблему, если без курсоров комменты ну никак не перенести?
А если 2-й курсор также объявить в разделе описаний, а в цикле его просто открывать и закрывать?
Код:
select * from comment_table_from where news_id=i_id
</span></span>
Цитата: GHopper
у меня второй курсор зависит от первого. Тоесть запрос во втором курсоре бурет вида
где i_id - индентификатор новости, который мы получим лишь после открытия курсора cur1
</span></span>
Код:
select * from comment_table_from where news_id=i_id
</span></span>
А разве в MySQL нельзя сделать так:
Код:
А в цикле присваивать переменной param значение id из 1-го курсора и открывать 2-й курсор
Попробуй сделать вызов процедуры вместо объявления курсора, а этой процедуре уже работай с новым курсором...
до вызова процедуры сам не додумался, и второй курсор можно объявить в разделе описаний (во всяком случае синтаксис позволяет).
Мне самому задачу упростили и я решил проблему INSERT ... SELECT.
Код:
...
DECLARE cur1 CURSOR FOR SELECT id FROM table1;
DECLARE cur2 CURSOR FOR SELECT id FROM table2;
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done1 = 1;
...
DECLARE cur1 CURSOR FOR SELECT id FROM table1;
DECLARE cur2 CURSOR FOR SELECT id FROM table2;
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done1 = 1;
...
В последней записи мы создаем условие на то, что все данные выбраны. Если оно выполняется SQLSTATE получает значение '02000' и следом выполняется условие (в моем случае done1 = 1). Но как нам создать два таких условия для двух разных курсоров? Ведь если мы запустим внутренний курсро он у нас закончится SQLSTATE='02000' и все DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' выполнятся! Это повлечет за собой закрытие и первого курсора!
объявляя
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;
вы задаете хендлер на исключительную ситуацию при окончании данных в курсоре, он срабатывает когда курсор опустошается и в переменную done заносится 1. Т.е. мне кажется хэндлер должен быть 1 на оба курсора, просто перед открытием внутреннего курсора нужно сохранять текущее значение переменной done, присваивать done=0, обрабатывать внутренний курсор и затем восстанавливать прежнее значение done. Я надеюсь моя мысль понятна.