Система типов (XQuery)
XQuery является строго типизированным языком для типов схемы и слабо типизированным языком для нетипизированных данных. Ниже приведены стандартные типы данных языка XQuery:
Встроенные типы XML-схем в пространстве имен http://www.w3.org/2001/XMLSchema.
Типы, определенные в пространстве имен http://www.w3.org/2004/07/xpath-datatypes.
В этом разделе также описано следующее:
Сравнение типизированных и строковых значений узла.
Сопоставление типов последовательности, возвращаемой выражением.
Встроенные типы 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():
Функция Функция data (XQuery) возвращает типизированное значение узла.
Функция Функция string (XQuery) возвращает строковое значение узла.
В представленной ниже коллекции 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() для извлечения типизированных значений узлов. |