Учебное пособие (1075724), страница 23
Текст из файла (страница 23)
Синтаксис:SOME | EVERY $переменная IN выражение (, $переменная_n INвыражение_n)* SATISFIES условие214Выражение всегда возвращает true или false. EVERY (И) означает, чтоусловие должно выполняться для всех значений, SOME (ИЛИ) – хотя бы дляодного.Таблица 4.19. Примеры запросов. Выражения some и every.some $i in (1 to 3) satisfies $i<2every $i in (1 to 3) satisfies $i<2let $rez :=truefalsetrueАналогичные<rez>{ for $i in (1 to 3) returnвыражения<r>{$i<2}</r> }</rez>использованиеreturnFLWOR.сАналог SOMEif (fn:count($rez/r[. = fn:true()])> 0 )then fn:true()else fn:false()let $rez :=falseАналог EVERYtrueВозможно<rez>{ for $i in (1 to 3) return<r>{$i<2}</r> }</rez>returnif (fn:count($rez/r[.
= fn:false()])> 0 )then fn:false()else fn:true()some $x in (1, 2, 3),$y in (2, 3, 4)satisfies $x + $y = 4указаниенесколькихпеременных(пример изспецификации)215some $x as xs:integer intrueВозможноуказание типов(1, 2, 3),данных с$y as xs:integer inпомощью AS(2, 3, 4)satisfies $x + $y = 4let $doc1 :=trueСтроитсяdoc("/db/Examples/doc1.xml"),декартово$doc2 := doc("/db/Examples/doc2.xml")произведениеreturnэлементов «e» изsome $i in $doc1//e, $j in $doc2//eпервого ивторогоsatisfies $i=$jlet $doc1 :=falsedoc("/db/Examples/doc1.xml"),документа,поэтому someвозвращает true,$doc2 := doc("/db/Examples/doc2.xml")а everyreturnвозвращает falseevery $i in $doc1//e, $j in $doc2//esatisfies $i=$jlet $rez := <q> {let $doc1 :=doc("/db/Examples/doc1.xml"),$doc2 := doc("/db/Examples/doc2.xml")falseВ переменной$rez в элементах<p> i=j.
Ноfor $i in $doc1//e, $j in $doc2//eвыраженияwhere $i=$j$rez/p/ireturn <p><i>{$i}</i><j>{$j}</j></p>и $rez/p/j} </q>разделяютreturnevery $i1 in $rez/p/i, $j1 in$rez/p/jsatisfies $i1=$j1выборку наотдельныеподзапросы, покоторым216строитсядекартовопроизведение. Вдекартовомпроизведении невсегда i=j.Поэтому everyвозвращает false.let $rez := <q> {truelet $doc1 :=Правильныйвариантdoc("/db/Examples/doc1.xml"),$doc2 := doc("/db/Examples/doc2.xml")for $i in $doc1//e, $j in $doc2//ewhere $i=$jreturn <p><i>{$i}</i><j>{$j}</j></p>} </q>returnevery $p in $rez/psatisfies $p/i = $p/jСледующие типы конструкций XQuery, как правило, могут использоватьсяреже, чем предыдущие.4.3.12 Действия над множествамиВозможны следующие действия над множествами: union (или |) – объединение множеств intersect – пересечение множеств except – первое множество минус второе множествоДействия нельзя выполнять над атомарными элементами, только над узлами.217Привыполнениидействийнадмножествамииспользуетсяпонятиеидентичности (identity) элементов.
Каждый элемент идентичен себе и неидентичен другим элементам.При выполнении действий два элемента считаются одинаковыми, если ониидентичны (то есть это один и тот же элемент). Если два полностью совпадающихэлемента находятся в разных документах (или разных частях документа), то онине идентичны и не будут считаться совпадающими при выполнении действий надмножествами.Таблица 4.20. Примеры запросов. Действия над множествами.letЗапрос не будет работать$set1:= <q><e>1</e><e>2</e><e>3</e></q>,правильно,$set2:= <q><e>1</e><e>2</e></q>return $set1/e union $set2/elet $set:= <q>таккакодинаковые элементы вдвухпеременныхнеидентичныВсе 4 элемента «е»<e id1="1" id2="2">1</e><e id1="1" id2="2">2</e><e id1="1">3</e><e id2="2">4</e></q>return $set/e[@id1="1"]union $set/e[@id2="2"]let $set:= <q>Элементы 1 и 2<e id1="1" id2="2">1</e><e id1="1" id2="2">2</e><e id1="1">3</e><e id2="2">4</e></q>218return $set/e[@id1="1"] intersect$set/e[@id2="2"]Элемент 3let $set:= <q><e id1="1" id2="2">1</e><e id1="1" id2="2">2</e><e id1="1">3</e><e id2="2">4</e></q>return $set/e[@id1="1"] except$set/e[@id2="2"]4.3.13 Сравнение узлов «is» возвращает истину, если узлы идентичны (являются одним и темже узлом). «<<» возвращает истину, если узел расположен в документе ранеедругого. «>>»возвращает истину, если узел расположен в документе позднеедругого.Таблица 4.21.
Примеры запросов. Сравнение узлов.let $q:=trueПервыйитретий<q><e>1</e><e>2</e><e>1</e></q>элементы «е» равны, ноreturn $q/e[1] = $q/e[3]не являются одним иlet $q:=falseтем же элементом<q><e>1</e><e>2</e><e>1</e></q>return $q/e[1] is $q/e[3]let $q:=true<q><e>1</e><e>2</e><e>1</e></q>return $q/e[1] << $q/e[3]219let $q:=false<q><e>1</e><e>2</e><e>1</e></q>return $q/e[1] >> $q/e[3]4.3.14 Выражения ordered и unorderedЕсли выражение находится внутри unordered {.
. .}, это означает, что порядоквыборки элементов не является важным и СУБД может выбирать элементы так,чтобы это было наиболее эффективно. Теоретически это может ускоритьвыполнение запроса. Существует аналогичная функция fn:unordered().Выражение ordered {. . .} оказывает обратное действие и может замедлитьвыполнение запроса.4.3.15 Выражения для работы с типами данныхИерархия типов данных в XQuery:220Рис. 4.6. Иерархия типов данных в XQuery.Конструкторы типов.xs:тип(выражение) – приведение выражения к данному типу.221Таблица 4.22.
Примеры запросов. Конструкторы типов.for $i in (1.12345678912345, 2.222,<float>1.12345678912345-1.1234568</float>3.333)<float>2.222 - 2.222</float>return<float>3.333 - 3.333</float><float>{$i} {xs:float($i)}</float>Выражение instance of Тип.Проверка того, что выражение заданного типа.Таблица 4.23. Примеры запросов. Выражение instance of.333 instance of xs:integertrueВыражение typeswitch – ветвление по типу.Таблица 4.24.
Примеры запросов. Выражение typeswitch.for $i in (1, xs:float(2.5),<integer>2</integer>"str")<float>5</float>return<string>str</string>typeswitch($i)case $i as xs:integerreturn<integer>{$i+1}</integer>case $i as xs:float return<float>{$i*2}</float>case $i as xs:string return<string>{$i}</string>default return "???"Выражения castable (проверка возможности приведения к типу данных) и cast(приведение к типу данных).222Таблица 4.25. Примеры запросов. Выражения castable и cast.for $i in (1, xs:float(2.5), "str")1 2.5 strreturnif ($i castable as xs:float)then $i cast as xs:floatelse if ($i castable as xs:integer)then $i cast as xs:integerelse $i cast as xs:string4.3.16 Обновление данных в базе данных (XQuery Update Facility)В таблице приведены лишь некоторые примеры запросов на обновлениеданных, которые работают в eXist.
Полный вариант можно найти в спецификации[XQuery Update, 2009].Таблица 4.26. Примеры запросов. Обновление данных.for $b inВставка содержимогоdoc("/db/Examples/Tree.xml")//branch[@id=5]элементаreturnupdate insert <insert_into/> into $bfor $b inВставка до элементаdoc("/db/Examples/Tree.xml")//branch[@id=5]returnupdate insert <insert_preceding/> preceding $bfor $b inВставка после элементаdoc("/db/Examples/Tree.xml")//branch[@id=5]returnupdate insert <insert_following/> following $bfor $b inЗамена элементаdoc("/db/Examples/Tree.xml")//branch[@id=5]return223update replace $b with <Replaced/>for $b inЗамена содержимогоdoc("/db/Examples/Tree.xml")//branch[@id=2]элементаreturnupdate value $b with <Update_Value/>for $b inПереименованиеdoc("/db/Examples/Tree.xml")//branch[@id=4]элементаreturnupdate rename $b as <tag>Branch_Renamed</tag>Удалениеfor $b indoc("/db/Examples/Tree.xml")//branch[@id=2]returnupdate delete $b4.3.17 Создание серверных сценариев на языке XQueryСерверные сценарии в eXist позволяют создавать веб-приложения на языкеXQuery.
Эта технология является аналогом таких технологий, как ASP, JSP, PHP.Серверные сценарии в eXist делятся на две группы:1. Сценарии (содержат запрос и функции). Могут быть запущены навыполнение.2.Библиотечныемодули(содержаттолькофункции,могутбытьиспользованы в сценариях).Для запуска следующих примеров их необходимо загрузить в каталог«Examples» и запускать путем нажатия на гиперссылки с именами файлов.Пример 4.2.module_1.xql – пример простого сценария.xquery version "1.0";(: Объявление версии :)224(: Возможно указание кодировки, например :)(: xquery version "1.0" encoding "utf-8"; :)(: ++++++++++++++++++++++++++++++++++++++++++++++++++++++ :)(: Пролог.
Объявление импортируемых модулей, опций, переменных,функций :)(: ++++++++++++++++++++++++++++++++++++++++++++++++++++++ :)(: Импорт модулей, соответствующих объектам request и session :)import module namespace request="http://existdb.org/xquery/request";import module namespace session="http://existdb.org/xquery/session";(: Опция, задающая вывод в виде HTML-страницы :)declare option exist:serialize "method=xhtml media-type=text/html";(: Объявление переменных :)declare variable $var1 as xs:integer := 300;(: Объявление функций :)(: Локальные функции объявляются с префиксом local: :)declare function local:function1($ParamUpper as xs:integer, $Base asxs:integer) as xs:integer*{for $i in 1 to $ParamUpper(: В функции можно использовать глобальные переменные :)return $var1 + $Base + $i};(: ++++++++++++++++++++++++++++++++++++++++++++++++++++++ :)(: Основной запрос :)(: ++++++++++++++++++++++++++++++++++++++++++++++++++++++ :)<html><body>225{(for $i in 1 to 5return <P>{$i} - {local:function1($i,30)}</P>),(for $i in 1 to 5return <P>{$i} - {local:function1($i,30)}</P>)}</body></html>Результат выполнения:Рис.
4.7. Результат выполнения примера 4.2.Пример 4.3.module_2.xql – пример сценария, использующего библиотечный модульxquery version "1.0";226(: Объявление версии :)(: Возможно указание кодировки, например :)(: xquery version "1.0" encoding "utf-8"; :)(: ++++++++++++++++++++++++++++++++++++++++++++++++++++++ :)(: Пролог. Объявление импортируемых модулей, опций, переменных,функций :)(: ++++++++++++++++++++++++++++++++++++++++++++++++++++++ :)(: Импорт модулей, соответствующих объектам request и session :)import module namespace request="http://existdb.org/xquery/request";import module namespace session="http://existdb.org/xquery/session";(: Импорт библиотечного модуля с помощью конструкцииimport module namespace префикс_пространства_имен ="идентификатор_пространства_имен" at "путь и имя файла.xqm"; :)import module namespace lib_module_333 = "http://lib_module_1" at"lib_module.xqm";(: Опция, задающая вывод в виде HTML-страницы :)declare option exist:serialize "method=xhtml media-type=text/html";(: ++++++++++++++++++++++++++++++++++++++++++++++++++++++ :)(: Основной запрос :)(: ++++++++++++++++++++++++++++++++++++++++++++++++++++++ :)<html><body>{(for $i in 1 to 5return <P>{$i} - {lib_module_333:function1($i,30)}</P>227(: Функция вызывается не через префикс local:, а черезпрефикс lib_module_333: :)),(<HR/>),(: Для обращения к переменной из модуля используется префикс:)(<P>$lib_module_1:var1 = {$lib_module_333:var1}</P>)(: Выражения (...),(...),(...) выполняются последовательно :)(: Если в выражении выводится статический тэг, то он долженбыть один, например (<HR/>) :)(: Следующая конструкция вызовет ошибку, так как в нейвыводится два тэга <HR> и <P> :)(: (<HR/><P>$lib_module_1:var1 = {$lib_module_333:var1}</P>):)(: Возможно группировать такие конструкции в тэг верхнегоуровня :)(: Следующая конструкция будет правильной :)(: (<DIV> <HR/> <P>$lib_module_1:var1 ={$lib_module_333:var1}</P> </DIV>) :)(: Конструкция, которая выводит несколько тэгов <P> внутриFLWOR также будет правильной,так как FLWOR является одним выражением :)}</body></html>lib_module.xqm – файл библиотечного модуля.xquery version "1.0";(: Объявление версии :)(: Возможно указание кодировки, например :)228(: xquery version "1.0" encoding "utf-8"; :)(: Объявление библиотечного модуля :)module namespace lib_module_1 = "http://lib_module_1";(: ++++++++++++++++++++++++++++++++++++++++++++++++++++++ :)(: Пролог.















