XQuery и статическая типизация
В SQL Server XQuery является языком со статической типизацией. Это означает, что при компиляции запросов, если выражение возвращает значение, тип или мощность которого неприемлемы для указанной функции или оператора, будет выдана ошибка преобразования типов. В дополнение к этому статическая проверка типов может также обнаружить несоответствие типа выражения пути в типизированном документе XML. Компилятор XQuery сначала применяет фазу нормализации, во время которой добавляются неявные операции (например атомизация), а затем производит статический вывод и статическую проверку типов.
Статический вывод типов
Во время операции вывода статического типа определяется тип возвращаемого значения выражения. Для этого берутся статические типы входных параметров и статическая семантика операции и выводится статический тип результата. Например статический тип выражения «1 + 2.3» определяется следующим образом.
- Статический тип «1» равен xs:integer, а статический тип «2.3» — xs:decimal. На основе динамической семантики, статическая семантика операции + преобразует целочисленное значение в десятичное и затем возвращает десятичное значение. Таким образом выведенным статическим типом будет xs:decimal.
Для нетипизированных экземпляров XML имеются специальные типы, обозначающие, что данные нетипизированы. Эти сведения используются при статической проверке типов и для неявного преобразования некоторых типов.
Для типизированных данных входной тип выводится из коллекции схем XML, ограничивающей экземпляр типа данных XML. Например, если схема допускает только наличие элементов типа xs:integer, то результатом выражения пути, использующего этот элемент, будет нуль и более элементов типа xs:integer. Это часто обозначается выражениями вроде element(age,xs:integer)*
, где символ звездочки (*) указывает мощность результирующего типа. В приведенном примере результатом выражения может стать нуль и более элементов с именем «age» и типом xs:integer. Остальные мощности: ровно 1, что выражается указанием только имени типа; 0 или 1, что выражается указанием вопросительного знака (?); 1 и более, что выражается указанием плюса (+).
Иногда вывод статического типа может определить, что выражение всегда возвращает пустую последовательность. Например, если выражение пути типизированного типа данных XML ищет элемент <name> внутри элемента <customer> (/customer/name), а схема не допускает содержание элементов <name> внутри элементов <customer>, статический вывод типа приведет к пустому результату. Этот эффект применяется для выявления неправильных запросов, то есть будет выдана статическая ошибка, если только этим выражением не было () или data( () ).
Подробное описание правил вывода содержится в формальной семантике спецификации XQuery. Корпорация Майкрософт только незначительно изменила их для работы с типизированными экземплярами типа данных XML. Наиболее важное отличие от стандарта заключается в том, что неявный узел документа знает тип данных экземпляра XML. Поэтому выражение пути в форме «/age» на основе этих сведений будет точно типизировано.
При помощи приложения SQL Server Profiler можно просмотреть статические типы, возвращаемые при компиляции запросов (событие: TSQL -> XQuery Static Type).
Статическая проверка типов
Статическая проверка типов гарантирует, что на стадии выполнения операции будут переданы только те значения, которые имеют соответствующие типы данных. Поскольку эти типы на стадии выполнения не надо проверять, потенциальные ошибки могут быть обнаружены на ранней стадии компиляции, что позволяет повысить производительность. Однако статическая типизация требует точности формулировок при написании запроса.
Ниже приведены все применимые типы:
- типы, явно допустимые для функции или операции;
- подтипы явно допустимых типов.
Подтипы определяются на основе правил создания подтипов схемы XML при наследовании по ограничению или по расширению. Например тип S является подтипом типа T, если все значения, которые имеет тип S, являются также экземплярами типа T.
Кроме того, в соответствии с иерархией типов схемы XML, все целочисленные значения являются также и десятичными. Но при этом не все десятичные значения являются целочисленными. Иными словами, целочисленное является подтипом десятичного, но не наоборот. Например операция + принимает только значения определенных типов, например числовых типов xs:integer, xs:decimal, xs:float и xs:double. Если переданные значения относятся к другим типам (например к xs:string), оператор выдает ошибку типа данных. Это называется строгой типизацией. Значения других типов, например атомарного типа, применяемого для обозначения нетипизированного XML, могут быть неявно преобразованы в значение типа, поддерживаемого для данной операции. Это называется слабой типизацией.
Если требуется неявное преобразование, статическая проверка типов гарантирует, что операции будут переданы только значения допустимых типов с верной мощностью. Для значения «"строка" + 1» будет определено, что статическим типом значения «строка» является xs:string. Поскольку этот тип недопустим для операции +, будет выдана ошибка типа данных.
При сложении результатов произвольного выражения E1 и произвольного выражения E2 (E1 + E2) статический вывод типов сначала определяет статические типы E1 и E2, а затем сверяет их с типами, допустимыми для данной операции. Например, если статический тип E1 может быть либо xs:string, либо xs:integer, проверка статического типа выдает ошибку типа данных, даже если некоторые значения на стадии выполнения могут оказаться целочисленными. То же самое может произойти, если статический тип E1 будет равен xs:integer*. Поскольку операция + принимает одно и только одно целочисленное значение, а выражение E1 может вернуть 0 или более 1, статическая проверка типов выдаст ошибку.
Как говорилось ранее, вывод типов часто определяет тип более свободно, чем известно о передаваемом типе данных пользователю. В таких случаях пользователь должен переписать запрос. Некоторые наиболее распространенные причины этого:
- Тип выводит более общий тип: супертип или объединение типов. Если тип является атомарным, для обозначения действительного статического типа необходимо применить выражение явного преобразования или функцию конструктора. Например, если выведенный тип выражения E1 может быть xs:string или xs:integer, а операции сложения требуется xs:integer, следует указывать
xs:integer(E1) + E2
, а неE1+E2
. Это выражение на стадии выполнения может завершиться ошибкой, если символьное значение не сможет быть преобразовано в xs:integer, но зато теперь выражение будет проходить статическую проверку типов. В SQL Server 2005 такое выражение отображается в пустую последовательность. - Тип выводит мощность, большую, чем в действительности содержат данные. Это часто происходит из-за того, что тип данных xml может содержать более одного элемента верхнего уровня, и это не может быть ограничено коллекцией схем XML. Чтобы ограничить статический тип и гарантировать, что передается именно не более одного значения, следует применять позиционный предикат [1]. Например, чтобы сложить значение 1 со значением атрибута «c» элемента «b», вложенного в элемент верхнего уровня «a», необходимо указать (/a/b/@c)[1]+1. Кроме этого, вместе с коллекцией схем XML может использоваться ключевое слово DOCUMENT.
- Некоторые операции, например ось parent, при выводе теряют сведения о типе. Если выражение приводит к ошибке статической типизации, не пользуйтесь ими и перепишите запрос.
См. также
Другие ресурсы
Запрос XQuery к типу данных xml