Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Problem z użyciem kursora w procedurze
Forum PHP.pl > Forum > Bazy danych > MySQL
piotr.k
MySql ver. 5.1.54

W procedurze próbuje 2 razy otworzyć ten sam cursor ( SELECT zdefiniowany jest jako DECLARE ... CURSOR ...).

Za pierwszym razem, CURSOR działa bez zarzutu.

Otwieram CURSOR ( OPEN cur_jakis).
Pobieram dane.
Na koniec, CURSOR jest zamykany ( CLOSE cur_jakis )

Za drugim razem.
Otwieram CURSOR ( OPEN cur_jakis )
Brak danych
Na koniec, CURSOR jest zamykany ( CLOSE cur_jakis )


Dlaczego przy drugim otwarciu CURSOR-a, mam brak danych questionmark.gif
Może to taka cecha mysql-a i aby to osiągnąć należy wiele razy przewołać procedurę ?
darko
Tutaj masz przykład takiego kursora w procedurze i jest tam flaga exit_loop ustawiana i sprawdzana za każdym razem, kiedy kursor będzie wskazywał na ostatni wiersz w zbiorze oraz takie cuś:
  1. DECLARE CONTINUE HANDLER FOR NOT FOUND SET exit_loop = TRUE;
piotr.k
Problem polega na tym, że ponowne otwarcie tego samego CURSOR-a w procedurze,
kończy się brakiem danych, jak i również kolejne otwarcia.

Tylko pierwsze otwarcie CURSOR-a, zwraca dane.
Nie wiem czy to błąd czy też cecha MySQL-a


Poniżej przedstawiam działający przykład, powtórnego otwarcia CURSOR-a, który sprawia problem.
Procedura 2 razy otwiera CURSOR cur_sel.
Za drugim, otwarcie i pobranie danych kończy się natychmiast brakiem danych .


Wywołanie:
call test_cursor(@txt); select @txt

Wynik:
1) il=91 2) il=0

Interpretacja:
1-e otwarcie kursora zwróciło 91 rekordów, ale 2-e już zero(!).




Kod
--  call test_cursor(@txt); select @txt
-- DROP PROCEDURE IF EXISTS test_cursor;
CREATE PROCEDURE test_cursor( out p_txt char(70)  )

proc_block: BEGIN

DECLARE is_end_cursor int DEFAULT 0;
DECLARE v_id    BIGINT DEFAULT 0;
DECLARE il          INT DEFAULT 0;
DECLARE txt        CHAR(80) DEFAULT "";


DECLARE cur_sel CURSOR FOR
   SELECT id FROM pk_jakas_tabela
;
DECLARE CONTINUE HANDLER FOR NOT FOUND   SET is_end_cursor = TRUE;

--  start 1 petla ----------------------

OPEN cur_sel;
loop_sel: LOOP
    FETCH cur_sel INTO v_id;
    IF( is_end_cursor ) THEN LEAVE loop_sel; END IF;
    SET il=il+1;
END LOOP loop_sel;
CLOSE cur_sel;

--  end 1 petla ----------------------


-- Budowa tekstu
SET txt=concat("1) il=", convert(il, char(10)) );
SET p_txt=concat(IFNULL(p_txt,""), txt);



--  start 2 petla ----------------------

SET il=0;

OPEN cur_sel;
loop_sel2: LOOP
    FETCH cur_sel INTO v_id;
    IF( is_end_cursor ) THEN LEAVE loop_sel2; END IF;
    SET il=il+1;
END LOOP loop_sel2;
CLOSE cur_sel;

--  end2 petla ----------------------

-- Budowa tekstu: 2) il= ....
SET txt=concat(" 2) il=", convert(il, char(10)) );
SET p_txt=concat(IFNULL(p_txt,""), txt);

END proc_block;
irmidjusz
po wyjściu z pierwszej pętli ustaw is_end_cursor na false
piotr.k
Dziękuję za pomoc.

Ustawienie:
SET is_end_cursor=FALSE;
rozwiązało problem.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.