Обработка ошибок (XQuery)
Спецификация W3C позволяет стирать ошибки типа данных статически или динамически и определяет статические, динамические ошибки и ошибки типа данных.
Компиляция и обработка ошибок
При обработке синтаксически неверных выражений Xquery и инструкций XML DML возвращаются ошибки компиляции. На этапе компиляции проверяется правильность выражений XQuery и DML-инструкций в контексте статических типов и используются XML-схемы для вывода типов типизированного XML. Если выражение может завершиться неудачей в период выполнения из-за нарушения безопасности типов, компилятор формирует ошибки статических типов. Примерами статических ошибок являются добавление строки к целому числу и запрос несуществующего узла типизированных данных.
Ошибки XQuery периода выполнения преобразуются в пустые последовательности — это отклонение от стандарта W3C. В результате запроса эти последовательности могут быть представлены как пустой XML или как значение NULL, что зависит от контекста вызова.
Явное приведение к правильному типу позволяет предотвращать статические ошибки, хотя ошибки приведения типов в период выполнения будут преобразовываться в пустые последовательности.
Статические ошибки
Статические ошибки возвращаются при помощи механизма ошибок языка Transact-SQL. В сервере SQL Server ошибки типа данных языка XQuery возвращаются статически. Дополнительные сведения см. в разделе XQuery и статическая типизация.
Динамические ошибки
В языке XQuery большинство динамических ошибок сопоставляется с пустой последовательностью («()»). Однако есть два исключения: условия переполнения в функциях агрегации языка XQuery и ошибки проверки правильности XML-DML. Обратите внимание, что большинство динамических ошибок сопоставляется с пустой последовательностью. В противном случае выполнение запроса, которое получает преимущества от XML-индексов, может возбудить непредвиденные ошибки. Поэтому, чтобы обеспечить эффективное выполнение без формирования непредвиденных ошибок, компонент SQL Server Database Engine сопоставляет динамические ошибки с ().
Часто в ситуации, когда динамическая ошибка возникнет внутри предиката, отсутствие сигнала об ошибке не меняет семантику, потому что () сопоставляется со значением False. Однако в некоторых случаях возврат () вместо динамической ошибки может вызвать непредвиденные результаты. Следующие примеры иллюстрируют данную ситуацию.
Пример. Использование функции avg() с аргументом типа String
В следующем примере метод функция avg вызывается для вычисления среднего арифметического трех значений. Одно из этих значений представляет собой строку. Поскольку в этом случае экземпляр XML не типизирован, все данные в нем принадлежат к нетипизированному элементарному типу. Перед вычислением среднего арифметического функция avg() приводит эти значения к xs:double. Однако значение "Hello" не может быть приведено к xs:double, и оно создает динамическую ошибку. В таком случае вместо возвращения динамической ошибки приведение "Hello" к xs:double вызывает пустую последовательность. Функция avg() пропускает данное значение, вычисляет среднее арифметическое двух других значений и возвращает 150.
DECLARE @x xml
SET @x=N'<root xmlns:myNS="test">
<a>100</a>
<b>200</b>
<c>Hello</c>
</root>'
SELECT @x.query('avg(//*)')
Пример. Использование функции not
Когда используется не функция в предикате, например /SomeNode[not(Expression)], и выражение вызывает динамическую ошибку, вместо ошибки будет возвращена пустая последовательность. Применение not() к пустой последовательности вместо ошибки возвращает значение True.
Пример. Приведение строк
В следующем примере строковая константа "NaN" приводится к типу данных xs:string, затем к xs:double. Результатом является пустой набор строк. Несмотря на то что строка "NaN" не может успешно быть приведена к типу xs:double, это не может быть определено до момента выполнения, потому что сначала строка приводится к типу xs:string.
DECLARE @x XML
SET @x = ''
SELECT @x.query(' xs:double(xs:string("NaN")) ')
GO
Однако в данном примере статическая ошибка возникает.
DECLARE @x XML
SET @x = ''
SELECT @x.query(' xs:double("NaN") ')
GO
Ограничения реализации
Функция fn:error() не поддерживается.