Контекст выражения и вычисление запросов (XQuery)
Контекст выражения представляет собой данные, используемые для анализа и оценки. Ниже приводятся две фазы оценки XQuery:
Статический контекст — это фаза компиляции запроса. Иногда ошибки могут возникать в процессе такого статического анализа запроса, основанного на доступных данных.
Динамический контекст — это фаза выполнения запроса. Даже если в запросе нет статических ошибок, таких как ошибки компиляции, он может вернуть ошибки во время исполнения.
Статический контекст
Инициализация статического контекста относится к процессу объединения данных для статического анализа выражения. В рамках инициализации статического контекста выполняются следующие операции:
Политика пробела границы устанавливается на чередование. Таким образом, пробел границы не сохраняется конструкторами any element и attribute в запросе. Например:
declare @x xml set @x='' select @x.query('<a> {"Hello"} </a>, <b> {"Hello2"} </b>')
Запрос возвращает следующий результат, поскольку пробел границы чередуется во время анализа выражения XQuery:
<a>Hello</a><b>Hello2</b>
Инициализируются связывания префикса с пространством имен для:
Набор стандартных пространств имен.
Любых пространств имен, определенных при помощи WITH XMLNAMESPACES. Дополнительные сведения см. в разделе Добавление пространств имен с помощью предложения WITH XMLNAMESPACES.
Любых пространств имен, определенных в прологе запроса. Обратите внимание на то, что объявления пространств имен в прологе могут отменять объявления пространств имен в WITH XMLNAMESPACES. Например, в следующем запросе WITH XMLNAMESPACES объявляет префикс (pd), связывающий его с пространством имен (http://someURI). Однако пролог запроса отменяет связывание в предложении WHERE.
WITH XMLNAMESPACES ('http://someURI' AS pd) SELECT ProductModelID, CatalogDescription.query(' <Product ProductModelID= "{ sql:column("ProductModelID") }" /> ') AS Result FROM Production.ProductModel WHERE CatalogDescription.exist(' declare namespace pd="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription"; /pd:ProductDescription[(pd:Specifications)]' ) = 1
Все такие связывания пространств имен разрешаются в процессе инициализации статического контекста.
При запросе типизированного столбца или переменной xml компоненты коллекции XML-схем, связанные с этим столбцом или переменной, импортируются в статический контекст. Дополнительные сведения см. в разделе Сравнение типизированного и нетипизированного XML.
Функция приведения также становится доступной в статическом контексте для каждого атомарного типа в импортированных схемах. Это продемонстрировано в следующем примере. В данном примере запрос производится к типизированной переменной xml. Коллекция XML-схем, связанная с данной переменной, определяет атомный тип myType. Во время статического анализа доступна функция приведения для этого типа myType(). Выражение запроса (ns:myType(0)) возвращает значение myType.
-- DROP XML SCHEMA COLLECTION SC -- go CREATE XML SCHEMA COLLECTION SC AS '<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="myNS" xmlns:ns="myNS" xmlns:s="https://schemas.microsoft.com/sqlserver/2004/sqltypes"> <import namespace="https://schemas.microsoft.com/sqlserver/2004/sqltypes"/> <simpleType name="myType"> <restriction base="int"> <enumeration value="0" /> <enumeration value="1"/> </restriction> </simpleType> <element name="root" type="ns:myType"/> </schema>' go DECLARE @var XML(SC) SET @var = '<root xmlns="myNS">0</root>' -- specify myType() casting function in the query SELECT @var.query('declare namespace ns="myNS"; ns:myType(0)')
В следующем примере в выражении указывается функция приведения для встроенного типа XML int.
declare @x xml set @x = '' select @x.query('xs:int(5)') go
После инициализации статического контекста анализируется (компилируется) выражение запроса. Статический анализ включает следующее:
Анализ запроса.
Разрешение функции и имен типа, указанного в выражении.
Статическую типизацию запроса. Это гарантирует безопасность типа запроса. Например, следующий запрос возвращает статическую ошибку, поскольку оператор + требует аргументы типа-примитива:
declare @x xml set @x='' SELECT @x.query('"x" + 4')
В следующем примере оператор value() требует одноэлементного запроса. Как указано в XML-схеме, допускается наличие нескольких элементов <Elem>. Статический анализ выражения определяет, что это небезопасный тип, и возвращает статическую ошибку. Чтобы устранить ошибку, выражение должно быть переписано таким образом, чтобы явно указать одноэлементный запрос (data(/x:Elem)[1]).
DROP XML SCHEMA COLLECTION SC go CREATE XML SCHEMA COLLECTION SC AS '<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="myNS" xmlns:ns="myNS" xmlns:s="https://schemas.microsoft.com/sqlserver/2004/sqltypes"> <import namespace="https://schemas.microsoft.com/sqlserver/2004/sqltypes"/> <element name="Elem" type="string"/> </schema>' go declare @x xml (SC) set @x='<Elem xmlns="myNS">test</Elem><Elem xmlns="myNS">test2</Elem>' SELECT @x.value('declare namespace x="myNS"; data(/x:Elem)[1]','varchar(20)')
Дополнительные сведения см. в разделе XQuery и статическая типизация.
Ограничения реализации
Далее приводятся ограничения, связанные со статическим контекстом:
Режим совместимости XPath не поддерживается.
Для структуры XML доступен только режим структуры чередования. Это значение установлено по умолчанию. Таким образом, тип узла создаваемых элементов типа xdt:untyped и атрибуты являются типом xdt:untypedAtomic.
Поддерживается только режим упорядоченной сортировки.
Поддерживается только политика чередующегося пробела XML.
Основная функциональность URI не поддерживается.
Функция fn:doc() не поддерживается.
Функция fn:collection() не поддерживается.
Детектор запросов XQuery со статической типизацией не предоставляется.
Используются параметры сортировки, связанные с типом данных xml. Всегда используются параметры сортировки по кодовым точкам Юникода.
Динамический контекст
Динамический контекст связан с данными, которые должны быть доступны во время выполнения выражения. Помимо статического контекста происходит инициализация следующих данных как части динамического контекста:
Фокус выражения, такой как элемент контекста, положение контекста и размер контекста, инициализируется следующим образом. Обратите внимание на то, что все эти значения можно отменить при помощи nodes() method.
Тип данных xml устанавливает элемент контекста и обрабатываемый узел для узла документа.
Положение контекста — это положение элемента контекста, который относится к обрабатываемому узлу изначально устанавливается в 1.
Размер контекста — это количество элементов в обрабатываемой последовательности изначально устанавливается в 1, поскольку всегда существует один узел документа.
Ограничения реализации
Далее приводятся ограничения, связанные с динамическим контекстом:
Контекстная функция Текущие дата и время, fn:current-date, fn:current-time и fn:current-dateTime не поддерживаются.
Неявные временные зоны установлены на UTC+0 и не могут быть изменены.
Функция fn:doc()не поддерживается. Все запросы выполняются для переменных и столбцов типа xml.
Функция fn:collection()не поддерживается.
См. также