Sławomir Gajowniczek

Sławomir Gajowniczek Nowe doświadczenia

Temat: Handler - Stored Procedure - MySQL

Witajcie.
Potrzebuję porady w zakresie obsługi handlerów dla cursora w procedurze MySQL. Sytuacja przedstawia się tak:

Mam zdefiniowane dwa kursory. Najpierw wykorzystuje jeden z nich do parsowania pewnych danych i zasilenia tymczasowej tabeli. Następnie drugi kursor działa na danych z tymczasowej tabeli i generuje mi wynikowe dane.

Problem polega na tym, że dla każdego kursora należy zadeklarować handler, który steruje iteracją.

declare continue handler for SQLSTATE '02000' set finished = true;


Podobno (idąć za StackOverflow) można izolować deficje handlerów poprzez użycie bloków BEGIN [...] END.
U mnie to nie działa. Otóż drugi kursor kończy pracę po wykonaniu jednego przejścia tj. przestawia zmienną innytaki na true. To wygląda tak, jakby kursor finalscen korzystał nadal z handlera zdefiniowanego w poprzednim bloku. Możecie pomóc?


DELIMITER $$

CREATE DEFINER=`ea`@`%` PROCEDURE `scenariopath`(IN param VARCHAR(45))
BEGIN
/* zmienne kursora 2 */
DECLARE xObject_Type INT(11);
....

/* zmienne kursora 2 */
DECLARE yObject_ID INTEGER(10);
....
/*
Cursor do analizy przygotowania tymczasowych danych
*/
DECLARE scenariocur CURSOR FOR
SELECT val,val2,val3
FROM xmlscenarios;

/*
Cursor do generacji danych docelowych
*/
DECLARE finalscen CURSOR FOR
SELECT val,val2,val3
FROM xmlscenariosextensions;

OPEN scenariocur;
scenarioparse: BEGIN

declare finished boolean default false;
declare continue handler for SQLSTATE '02000' set finished = true;
curloop: loop
fetch scenariocur into ...

if finished then
set finished = false;
leave curloop;
end if;

end loop curloop;
end scenarioparse;
close scenariocur;

/* CZESC GENERUJACA DOCELOWE DANE*/

OPEN finalscen;
generuj: BEGIN
declare innytaki boolean default false;
declare continue handler FOR SQLSTATE '02000' set innytaki = true;
curloop2: loop
fetch finalscen into ...
if innytaki then
set innytaki = false;
leave curloop2;
end if;

/* jakis kod */
end loop curloop2;
end generuj;
close finalscen;

/* PRINT DATA */

END
Ten post został edytowany przez Autora dnia 28.06.13 o godzinie 16:57
Nikodem Dobrzański

Nikodem Dobrzański Architekt systemu,
BizTech Konsulting
S.A.

Temat: Handler - Stored Procedure - MySQL

Zastanawiam się, dlaczego chcesz użyć kursora? Zazwyczaj wyprowadza się raporty poprzez widoki, ewentualnie zapytania zagnieżdżone. Od biedy można utworzyć i tablicę tymczasową. Kursory to ostateczność, bo działają wielokrotnie wolniej i stosowane są raczej do operacji zewnętrznych, niż bazodanowych.
Sławomir Gajowniczek

Sławomir Gajowniczek Nowe doświadczenia

Temat: Handler - Stored Procedure - MySQL

To co chcę uzyskać najsensowniej jest zrealizować procedurą i kursorem. Zasadniczo mam sytuację gdzie mam przechowywane dane XML w relacyjnej bazie danych. Część danych jest jednak przechowywana w tabelach. Zasada jest taka, że nie bardzo mogę grzebać w schemacie. Nowego nie mogę uzyskać.
Sama procedura parsuje XML do postaci tabeli tymczasowej a następnie te dane łączy z danymi z tej samej bazy przechowywanej w postaci relacyjnej.

Temat: Handler - Stored Procedure - MySQL

Sławomir G.:
U mnie to nie działa.

A tu działa
Sławomir Gajowniczek

Sławomir Gajowniczek Nowe doświadczenia

Temat: Handler - Stored Procedure - MySQL

Dziękuję. Dało to mi do myślenia i poszukania problemu gdzie indziej. Takowy też znalazłem.
To teraz ciekawostka.
Przy zastosowaniu konstrukcji typu
SELECT var INTO @uservar FROM x

a nastepnie wykorzystaniu zmiennej @uservar
np. w zapytaniu
SELECT x FROM y WHERE z = @uservar

gdzie pierwotne zapytanie nic nie zwraca - czyli zmienna jest pusta, nie powoduje to żadnego błędu ale status handlera dla kursora zostaje ustawiony na TRUE u kończy się wykonanie procedury.
Albert D.

Albert D. Software Developer

Temat: Handler - Stored Procedure - MySQL

W takim przypadku to chyba normalne działanie a nie ciekawostka.
Czemu ma byc blad jesli jest zdefiniowany handler?
A swoja drogą nie wiem dlaczego zamiast SQLSTATE '02000' nie zastosujesz skladni
DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = true;
Kod jest czytelniejszy i od razu wiadomo co obsluguje ten handler.

Następna dyskusja:

ADO, STORED PROCEDURE, PARA...




Wyślij zaproszenie do