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


Система типов (XQuery)

XQuery является строго типизированным языком для типов схемы и слабо типизированным языком для нетипизированных данных. Ниже приведены стандартные типы данных языка XQuery:

В этом разделе также описано следующее:

Встроенные типы XML-схемы

Встроенные типы XML-схемы обозначаются в пространстве имен стандартным префиксом xs. Вот некоторые из этих типов: xs:integer и xs:string. Поддерживаются все встроенные типы данных. Эти типы могут быть использованы при создании коллекции XML-схем.

При обращении к типизированному XML статические и динамические типы узлов определяются коллекцией XML-схем, связанной со столбцом, к которому происходит обращение. Дополнительные сведения о статических и динамических типах см. в разделе Контекст выражения и вычисление запросов (XQuery). Например, представленный ниже запрос указывается по отношению к типизированному столбцу xml (Instructions). В выражении instance of используется для проверки того, что типизированное значение возвращенного атрибута LotSize имеет тип данных xs:decimal.

SELECT Instructions.query('
   DECLARE namespace AWMI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";
   data(/AWMI:root[1]/AWMI:Location[@LocationID=10][1]/@LotSize)[1] instance of xs:decimal
') AS Result
FROM Production.ProductModel
WHERE ProductModelID=7

Эти типизированные данные предоставляются коллекцией XML-схем, связанной с указанным столбцом. Дополнительные сведения см. в разделе Представление типов данных XML в базе данных AdventureWorks2008R2.

Типы, определенные в пространстве имен типов данных XPath

Типы, определенные в пространстве имен http://www.w3.org/2004/07/xpath-datatypes обозначаются стандартным префиксом xdt. Эти типы обладают следующими свойствами:

  • Они не могут использоваться при создании коллекции XML-схем. Эти типы используются системой типов языка XQuery для XQuery и статическая типизация. Данные могут быть приведены к атомарным типам, например к типу xdt:untypedAtomic в пространстве имен xdt.

  • При обращении к нетипизированным XML статическим и динамическим типом узловых элементов является xdt:untyped, а значения атрибутов имеют тип xdt:untypedAtomic. Результатом выполнения метода query() являются нетипизированные XML. Это означает, что XML-узлы возвращаются в формате xdt:untyped и xdt:untypedAtomic соответственно.

  • Типы xdt:dayTimeDuration и xdt:yearMonthDuration не поддерживаются.

В следующем примере запрос задается на нетипизированной переменной XML. Выражение data(/a[1]) возвращает последовательность атомарных значений. Функция data() возвращает типизированное значение элемента <a>. Так как запрашиваемые XML не типизированы, возвращенное значение имеет тип xdt:untypedAtomic. Следовательно, выражение instance of возвращает значение True.

DECLARE @x xml
SET @x='<a>20</a>'
SELECT @x.query( 'data(/a[1]) instance of xdt:untypedAtomic' )

Вместо извлечения типизированного значения выражение (/a[1]) в следующем примере возвращает последовательность, состоящую из одного элемента <a>. Выражение instance of использует проверку элементов для контроля того, что возвращаемое выражением значение является узлом элемента типа xdt:untyped type.

DECLARE @x xml
SET @x='<a>20</a>'
-- Is this an element node whose name is "a" and type is xdt:untyped.
SELECT @x.query( '/a[1] instance of element(a, xdt:untyped?)')
-- Is this an element node of type xdt:untyped.
SELECT @x.query( '/a[1] instance of element(*, xdt:untyped?)')
-- Is this an element node?
SELECT @x.query( '/a[1] instance of element()')
ПримечаниеПримечание

Если при обращении к типизированным экземплярам XML в выражении запроса содержится родительская ось, сведения о статических типах результирующих узлов становятся недоступными. Однако динамические типы все равно остаются связанными с узлами.

Сравнение типизированных и строковых значений

Каждый узел содержит типизированное и строковое значение. Для типизированных XML-данных тип значения определяется коллекцией XML-схем, связанной со столбцом или переменной, к которым происходит обращение. Для нетипизированных XML-данных возвращенное значение имеет тип xdt:untypedAtomic.

Для получения значения узла можно использовать функции data() или string():

В представленной ниже коллекции XML-схем определяется целочисленный элемент <root>:

CREATE XML SCHEMA COLLECTION SC AS N'
<schema xmlns="http://www.w3.org/2001/XMLSchema">
      <element name="root" type="integer"/>
</schema>'
GO

В следующем примере выражение вначале получает типизированное значение /root[1], а затем добавляет к нему 3.

DECLARE @x xml(SC)
SET @x='<root>5</root>'
SELECT @x.query('data(/root[1]) + 3')

В следующем примере выражение завершается ошибкой, так как функция string(/root[1]) возвращает значение строкового типа. Затем указанное значение передается арифметическому оператору, который может работать только с числовыми операндами.

-- Fails because the argument is string type (must be numeric primitive type).
DECLARE @x xml(SC)
SET @x='<root>5</root>'
SELECT @x.query('string(/root[1]) + 3')

В следующем примере производится вычисление общей суммы атрибутов LaborHours. Функция data() получает типизированные значения атрибутов LaborHours из всех элементов <Location> модели продукта. Согласно XML-схеме, связанной со столбцом Instruction, атрибут LaborHours имеет тип данных xs:decimal.

SELECT Instructions.query(' 
DECLARE namespace AWMI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions"; 
             sum(data(//AWMI:Location/@LaborHours)) 
') AS Result 
FROM Production.ProductModel 
WHERE ProductModelID=7

Этот запрос возвращает значение 12,75.

ПримечаниеПримечание

Функция data() явно используется в данном запросе только в качестве учебного примера. Если не указано специально, функция sum() неявно применяет функцию data() для извлечения типизированных значений узлов.