Sql tárolt eljárás, handler, cursor

2011.08.16. 18:00 | arabiata | Szólj hozzá!

Címkék: select handler stored proc cursor if exists

 Vannak dolgok, amiket nem érdemes kliens oldalon erőltetni az adatmozgatás és sebesség miatt, hanem tárolt eljárásban megoldani. Előfordulhat olyan eset, amikor nem tudunk egy sima select vagy insert into ... (select...) utasítással feltölteni egy táblát, hanem végig kell a forrás táblát olvasni soronként. Erre való a cursor. Mutatok egy rövid példát és a benne rejlő buktatót is. 

Van két táblánk, amiket az "azon" mezők értéke kapcsol össze. A Tabla1_azon értéke alapján kell a Tabla2_mezo értékét kivenni, feldolgozni. Figyeljük meg, hogy egy sorban nem egyeznek meg az azonosító mezők értékei 

Tabla2

Tabla1

Tabla2_azon

Tabla2_mezo

Tabla1_azon

Ertek1

Mezo1

Ertek1

Ertek2

Mezo2

Ertek3

Ertek4

Mezo4

Ertek4

 

declare done default 0;

declare v_azon integer;

declare valtozo integer;

declare cursor1 for select tabla1_azon from tabla1;

declare continue handler for not found set done = 1;

 

open cur1;

read_loop: loop

fetch cursor1 into v_azon;

if done then

      leave read_loop;

end if;

 

if exists (select '' from tabla2 where tabla2_azon = v_azon) then

select tabla2_mezo into valtozo from tabla2 where tabla2_azon = v_azon;

end if; 

-- valtozo tovabbi feldolgozasa

end loop;

close cur1;

 A done változót a handler állítja be, ha nincs több olvasandó adat. Deklaráljuk a cursor-t, a handlert. Úgy hisszük, hogy ez akkor áll be, ha a cursor-nál elfogytak a sorok, vagyis végigolvastuk a Tabla1-et. Cursor nyitás, ciklus elejének beállítása, egyéb cirádák. A fetch beolvassa az into utáni változókba a következő sor mezőinek tartalmát. A mezők és változók számának, tipusának meg kell egyeznie. A ciklusból a fetch utáni if léptet ki.

Teoretikusan az "if exists" és az azt lezáró "end if" részt kommentezzük ki. Hivatalosan a Tabla2 megfelelő mező értékét visszakapjuk a valtozoban az azonosító mezők párosítása alapján.

És elkezdünk csalódni. Mert a mezo4 soha nem kerül be a valtozoba, pedig guvadt szemmel nézzük az azonosítók egyezését. Megvan a megoldás: bugos a mysql. A google is csak vonogatja a vállát, mindent a megadott példák szerint csináltunk.

Az igazi megoldás a következő: bár a handler-t rögtön a cursor után deklaráltuk, az nem akkor áll be, ha a cursor-nál elfogytak a beolvasandó sorok. Hanem ha valamit nem talál meg. Mint az állapota is mutassa - not found -. És mivel a handler hatóköre az egész tároltra kiterjed, nem csak a cursor-ra így a "select tabla2..." sornál billen be, mert a két azonosító egy helyen nem egyezik meg, vagyis not found.

Teoretikusan vegyük ki a kommenteket, és lőn. Csak azt a sort nem dolgozza fel a tárolt, ahol nem egyeznek az azonosítók.

Tehát egy tárolt eljárásban, ha cursor-t használunk, le kell kezelni minden hasonló ágat.

A bejegyzés trackback címe:

https://qtqt.blog.hu/api/trackback/id/tr893158404

Kommentek:

A hozzászólások a vonatkozó jogszabályok  értelmében felhasználói tartalomnak minősülnek, értük a szolgáltatás technikai  üzemeltetője semmilyen felelősséget nem vállal, azokat nem ellenőrzi. Kifogás esetén forduljon a blog szerkesztőjéhez. Részletek a  Felhasználási feltételekben és az adatvédelmi tájékoztatóban.

Nincsenek hozzászólások.
süti beállítások módosítása