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