Поделиться через


Контекст выражения и вычисление запросов (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
    

После инициализации статического контекста анализируется (компилируется) выражение запроса. Статический анализ включает следующее:

  1. Анализ запроса.

  2. Разрешение функции и имен типа, указанного в выражении.

  3. Статическую типизацию запроса. Это гарантирует безопасность типа запроса. Например, следующий запрос возвращает статическую ошибку, поскольку оператор + требует аргументы типа-примитива:

    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()не поддерживается.