Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

mysql5 PROCEDURE CURSOR

333
25 декабря 2007 года
GHopper
200 / / 28.12.2004
Здравствуйте!
Пишу процедуру экспорта новостей из одной БД в другую.

Код:
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;


Проблема в том, что вместе с новостю нужно перенести комменты к ней. Я хотел сделать вложенный цикл с курсором, но БД не дает определять переменные в процедуре после использования каких-либо операторов. Следовательно - я не могу определить курсор для таблицы с комментами в главном цикле обхода таблицы с новостями.

Как решить проблему, если без курсоров комменты ну никак не перенести?
8.2K
25 декабря 2007 года
Ora-cool
211 / / 20.09.2007
А если 2-й курсор также объявить в разделе описаний, а в цикле его просто открывать и закрывать?
333
25 декабря 2007 года
GHopper
200 / / 28.12.2004
у меня второй курсор зависит от первого. Тоесть запрос во втором курсоре бурет вида
 
Код:
select * from comment_table_from where news_id=i_id
где i_id - индентификатор новости, который мы получим лишь после открытия курсора cur1
</span></span>
8.2K
25 декабря 2007 года
Ora-cool
211 / / 20.09.2007
Цитата: GHopper
у меня второй курсор зависит от первого. Тоесть запрос во втором курсоре бурет вида
 
Код:
select * from comment_table_from where news_id=i_id
где i_id - индентификатор новости, который мы получим лишь после открытия курсора cur1
</span></span>


А разве в MySQL нельзя сделать так:


Код:
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;

А в цикле присваивать переменной param значение id из 1-го курсора и открывать 2-й курсор
35K
25 декабря 2007 года
Митяй
2 / / 25.12.2007
Попробуй сделать вызов процедуры вместо объявления курсора, а этой процедуре уже работай с новым курсором...
333
25 декабря 2007 года
GHopper
200 / / 28.12.2004
спасибо за советы!
до вызова процедуры сам не додумался, и второй курсор можно объявить в разделе описаний (во всяком случае синтаксис позволяет).

Мне самому задачу упростили и я решил проблему INSERT ... SELECT.
333
26 декабря 2007 года
GHopper
200 / / 28.12.2004
я тут подумал:
 
Код:
...
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' выполнятся! Это повлечет за собой закрытие и первого курсора!
8.2K
26 декабря 2007 года
Ora-cool
211 / / 20.09.2007
Я не силен в MySQL, но рискну предположить следующие:
объявляя
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;
вы задаете хендлер на исключительную ситуацию при окончании данных в курсоре, он срабатывает когда курсор опустошается и в переменную done заносится 1. Т.е. мне кажется хэндлер должен быть 1 на оба курсора, просто перед открытием внутреннего курсора нужно сохранять текущее значение переменной done, присваивать done=0, обрабатывать внутренний курсор и затем восстанавливать прежнее значение done. Я надеюсь моя мысль понятна.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог