XQuery (Bővebb infók: http://www.w3schools.com) ------ Az Oracle 10g-ben az XQuery lekérdezéseket az XMLQuery függvény segítségével valósították meg. Ennek a függvénynek a visszatérési értéke XML dokumentum vagy dokumentum töredék (vagy ilyenek sorozata). A korábbiakban látottakhoz hasonlóan meghívhatjuk rá a getStringval() MEMBER függvényt. Az Xquery nyelv a sorozatokra épül. Minden XQuery kifejezés eredménye egy sorozat. A sorozat 0 vagy több elemből áll, az elemek lehetnek skalár értékek vagy XML csomópontok. Az XQuery funkcionális nyelv. A nyelv kifejezései valamilyen visszatérési értékkel rendelkeznek. Ezek a visszatérési értékek többnyire sorozatok. A kifejezések a következők lehetnek: - literál, változó, függvény. A változók nevei $ jellel kezdődnek SELECT XMLQuery('"Blabla"' returning content).getStringval() FROM dual; SELECT XMLQuery('substring("bubu", 1,2)' returning content).getStringval() FROM dual; SELECT XMLQuery('count((1,2,3,4))' returning content).getStringval() FROM dual; SELECT XMLQuery ('2+2' returning content).getStringval() FROM dual; ---- 4 SELECT XMLQuery ('"2+2"' returning content).getStringval() FROM dual; ---- 2+2 - XPath kifejezés SELECT azon, XMLQuery('//Kolcsonzo[@nev="Gipsz Jakab"]/@nev' PASSING kolcs_spec RETURNING CONTENT) AS oszlop FROM kolcsonzes WHERE azon=1; - XQuery sorozat pl. (1,2,3,4) a beágyazott sorozatok kisimítva kezelendők (1, (2,3)) = (1,2,3), (1) = 1 SELECT XMLQuery ('(1,2,3,(4,5))' returning content).getStringval() FROM dual; - Literál konstrukciók, pl. 33 egy XML elem lesz SELECT XMLQuery ('33' returning content).getStringval() FROM dual; SELECT XMLQuery('(33,34)' returning content).getStringval() o1 FROM dual; - Dinamikus konstrukciók, a {} közötti rész kiértékelendő pl. a következő kifejezés {attribute att {2+3}, element elem2 {"szoveg", "szöveg2"}, text {"blabla"}} a kiértékelés után a következő lesz: szoveg szöveg2blabla SELECT XMLQuery (' {attribute att {2+3}, element elem2 {"szoveg", "szöveg2"}, text {"blabla"}} ' returning content).getStringval() FROM dual; - Aritmetikai és relációs kifejezések, pl. 2+3 (1,2,3,4) = (1,5) (5>3) eq true() 42 < $a + 5 SELECT XMLQuery('2+3' returning content).getStringval() FROM dual; SELECT XMLQuery('(1,2,3,4) = (1,5)' returning content) FROM dual; -> true !!! SELECT XMLQuery('(5 > 3) eq true()' returning content) FROM dual; - Feltételes kifejezés, pl. if (something < somethingElse) then expression1 else expression2 SELECT XMLQuery('if ((1,2,3) = (4)) then 1 else 2' returning content).getStringval() FROM dual; - Kvantor kifejezések, (minden, létezik) every kifejezés1 in kifejezés2 satisfies kifejezés3 some kifejezés1 in kifejezés2 satisfies kifejezés3 SELECT XMLQuery('every $a in (10,20,30) satisfies $a > 5' returning content) FROM dual; SELECT XMLQuery('every $a in () satisfies $a > 5' returning content) FROM dual; SELECT XMLQuery('some $a in (10,20,30) satisfies $a > 29' returning content) FROM dual; SELECT XMLQuery('some $a in () satisfies $a > 29' returning content) FROM dual; -> true ???? SELECT XMLQuery('some $a in (1,2), $b in (2,3) satisfies $a = $b' returning content) FROM dual; (Igaz-e, hogy minden Kolcsonzo kölcsönzött DVD-t?) SELECT XMLQuery('every $k in //Kolcsonzo satisfies $k//DVD' PASSING kolcs_spec RETURNING CONTENT) AS oszlop FROM kolcsonzes WHERE azon=1; - FLWOR kifejezés For, Let, Where, Order by, Return legalább egy For vagy Let, és a Return kötelező, a többi opcionális FOR egy vagy több változót értékhez rendel. A később szereplő változók használhatják a korábban szereplőket. pl. for $i in (3, 4), $j in ($i, 2+$i) esetén a második iterációban $i->4 $j->6 LET hasonló a FOR-hoz iteráció nélkül, pl. let $i := 3, $j := $i + 2 WHERE a változó hozzárendeléseket szűri meg ORDER BY a szűrés utáni eredményt rendezi RETURN visszaadja a rendezett eredményt egy sorozatként SELECT XMLQuery('for $a in (1,2,3), $b in (10,20) let $c := $a * $b where 1=1 return $c' returning content) FROM dual; SELECT XMLQuery ('for $i in (2, 3, 4), $j in ($i+5, 2) return ($i, $j)' returning content).getStringval() FROM dual; ----------------------- 2 7 2 2 3 8 3 2 4 9 4 2 SELECT XMLQuery ('for $i in (2, 3, 4) let $j:=$i+5 return ($i, $j)' returning content).getStringval() FROM dual; ----------- 2 7 3 8 4 9 -- Ez talán meglepő lehet, de ha beágyazott ciklusra gondolunk, akkor nem az SELECT XMLQuery ('for $i in (2, 3, 4), $j in ($i+5, 2) return $i' returning content).getStringval() FROM dual; ----------- 2 2 3 3 4 4 -- Hány kölcsönző van? Valójában a neveiket számoljuk meg. -- A külső ciklus csak egyszer fut le !!! SELECT XMLQuery ('for $i in /Kolcsonzesek let $j:=$i/Kolcsonzo/@nev return count($j)' passing kolcs_spec returning content).getStringval() FROM kolcsonzes WHERE azon=1; ----- 3 -- Ez egy kicsit mást adna SELECT XMLQuery ('for $i in //Kolcsonzo/@nev return count($i)' passing kolcs_spec returning content).getStringval() FROM kolcsonzes WHERE azon=1; ----- 1 1 1 (Adjuk meg a kölcsönzők nevét és az általuk kölcsönzött CD-k árának összegét) SELECT XMLQuery('for $k in //Kolcsonzo let $ar := sum($k//CD/Ar/text()) return ($k/@nev, $ar)' PASSING kolcs_spec RETURNING CONTENT) AS oszlop FROM kolcsonzes WHERE azon=1; (Vagy a fentit XML formátumban) SELECT XMLQuery('for $k in //Kolcsonzo let $ar := number(sum($k//CD/Ar/text())) return ' PASSING kolcs_spec RETURNING CONTENT).EXTRACT('/') AS oszlop FROM kolcsonzes WHERE azon=1; OSZLOP ------------------------------------------ - Reguláris kifejezések - Típus kifejezések, esetleg előfordulás jelölőkkel: (* 0 v. több) (? 0 v. 1) (+ 1 v. több) item(), node(), attribute(), element(), document-node(), text() item()+, attribute()?, document-node(element())* típusok kezelésére használatos operátorok: cast as, castable as, treat as, instance of, typeswitch, validate Példa XML dokumentum feldolgozására XQuery lekérdezéssel SELECT warehouse_name, XMLQuery( 'for $i in /Warehouse where $i/Area > 80000 return
{if ($i/RailAccess = "Y") then "true" else "false"}
' PASSING warehouse_spec RETURNING CONTENT) big_warehouses FROM oe.warehouses; WAREHOUSE_NAME BIG_WAREHOUSES -------------------- ------------------------------------------------------------ Southlake, Texas San Francisco New Jersey
false
Seattle, Washington
true
Toronto Sydney Mexico City Beijing Bombay Az XML dokumentumok a fenti esetben is formázatlanul (szöveges adatként) fognak megjelenni. Ha az XML típusú eredményre alkalmazzuk az EXTRACT metódust, úgy, hogy a megadandó XPath kifejezés '/' legyen, (vagyis a teljes dokumentumot adja vissza) akkor az eredmény formázva jelenik meg, azaz fa struktúrában. -> SELECT XMLQuery(...).EXTRACT('/') FROM ... Példa relációs adatok feldolgozására XQuery lekérdezéssel (ora:view használata) A relációs adatokat úgy kell felfogni, mintha a sorok egy külön ... elemben lennének, és minden oszlop ezen belül egy elem lenne. Lásd a DBMS_XMLGEN kimenetét (xml_fuggvenyek.txt). érték ... SELECT XMLQuery('for $i in ora:view("HR", "REGIONS"), $j in ora:view("HR", "COUNTRIES") where $i/ROW/REGION_ID = $j/ROW/REGION_ID and $i/ROW/REGION_NAME = "Asia" return $j' RETURNING CONTENT) AS asian_countries FROM DUAL; ASIAN_COUNTRIES ---------------------------------------------------------------------------- AU Australia 3 ... SG Singapore 3 SELECT XMLQuery( 'for $i in ora:view("OE", "WAREHOUSES")/ROW return {for $j in ora:view("HR", "LOCATIONS")/ROW where $j/LOCATION_ID eq $i/LOCATION_ID return ($j/STREET_ADDRESS, $j/CITY, $j/STATE_PROVINCE)} ' RETURNING CONTENT) eredmeny FROM DUAL; -------------------------------------------------------- 2014 Jabberwocky Rd Southlake Texas ... 1298 Vileparle (E) Bombay Maharashtra