Tárolt eljárás meghívása C# és Java kódból
2010. Március 3.
1. Feladat:
Az ügyfél csodálatos alkalmazása Back Office adatok szinkronizálásra biztosít tárolt eljárásokat. (Eredetileg úgy wolt, hogy a WS getter metódusai szarok, hibásak és lassúak voltak. Erre kitalálták, hogy úr isten, itt nagyon nagy mennyiségű adat van, meg hogy milyen nehéz már a WS-t kijavítani, és mennyivel egyszerűbb írni néhány tárolt eljárást. A business unit érje el közvetlenül a DB-t, és hívja meg az erre gyártott tárolt eljárásokat. Advanced Architecture!) A verzióváltás miatt ezeket is le akartam tesztelni. Még a végén nem működik az új rendszeren valamelyik, és a BU jön nekem sírni, hogy de miért…
2. A tárolt eljárás
A tárolt eljárás egy kicsit egyszerűsítve következőképpen van létrehozva:
Ahogy látható, a tárolt eljárásunk belső tárolt eljárásokat hív meg. A paraméterei:
- “RequestType” input paraméter: Melyik belső SP-t hívja meg.
- “RequestFlag” in/out paramétere: Pager megoldás. Ha több mint X record van amit vissza kellene adni, akkor visszaadja az első X-et, és a “RequestFlag” false lesz. Ilyenkor akkor újra meg kell hívni az SP-nket az előzőleg használt “RequestType”-pal és erre visszatér a következő X recorddal.
- XML visszatérési érték.
3. C# megoldás
Először lefuttattam azt a C# kódot, amit még az előző verzióhoz csináltam a business unitnak. (Igen, kicsit kézi vezérlésűek, meg kell nekik mutatni, hogy hogyan kell csinálni.) A pagerrel (“RequestFlag”) most nem foglalkozunk. Ez a következőképpen néz ki:
Ne felejtsük el az App.config-ba betenni a DB connection részleteit:
Ha lefuttatjuk pl.: “Users” requestType-pal, akkor az XmlDocument-ünk tartalmazni fogja a usereket.
4. A Java megoldás
Kis naívan azt hittem, hogy a Connection-ön meghívom a prepareCall() metódust ami ugye létrehozza nekem a CallableStatementet, ezen beállítom a paramétereit, hívok rajta egy execute()-ot, és a ResultSet-ből kiolvasom a végeredményt. Csak hogy ez így nem működik. Futottam vele néhány kört, mire debuggolás közben rájöttem, hogy ha sikerül feltartanom a programot az execute és a ResultSet processzálása között, akkor a ResultSet-ben feltűnik egy “XmlData” property amiben benne van a várt eredmény. Megpróbáltam az MS jdbc drivere helyett a JTDS jdbc drivert is használni, de azzal is hasonló lett az eredmény.
A következző thread segített megérteni mi is a probléma: http://dbaspot.com/forums/ms-sqlserver/223916-problem-boolean-return-parameter-callablestatement-execute.html (Thanks to Joe Weinstein @ BEA Systems).
A mi esetünkben a példa Java kód a következő:
Némi magyarázat: Azért van erre az egészre szükség, mert a tárolt eljárás végrehajtása elég sokáig is eltarthat. A CallableStatement getMoreResults() metódusa true-val tér vissza, ha a következő result egy ResultSet object. Az getUpdateCount() -1 -gyel tér vissza, ha befejeződött a tárolt eljárás. Tehát a kilépési feltételünk: nincs több result (a getMoreResult() false-sal tért vissza), és nincs is több updatelendő sora az SP-nek (a getUpdateCount() -1-et adott.)
A szép az egészben hogy a coding standards alapján ezért a while(true)/break megoldásért minimum nyilvánosan kivégeznének (De ahogy Joe@BEA írja, ez a legjobb kód feldolgozni bármilyen statementet).
