Gestion des erreurs (XQuery)

La spécification W3C permet de déclencher des erreurs de type statiquement ou dynamiquement et définit des erreurs statiques, dynamiques et de type.

Compilation et gestion des erreurs

Des erreurs de compilation sont renvoyées en cas de syntaxe incorrecte des expressions Xquery et des instructions XML DML. La phase de compilation permet de vérifier l'exactitude des types statiques des expressions XQuery et des instructions DML, et d'utiliser des schémas XML pour les inférences de type pour le code XML typé. Des erreurs de type statique sont générées si une expression risque d'échouer lors de l'exécution suite à la violation de la cohérence des types. On trouve parmi les erreurs statiques l'ajout d'une chaîne à un entier ou encore l'interrogation d'un nœud inexistant pour des données typées.

Conformément à la norme du W3C, les erreurs d'exécution XQuery sont converties en séquences vides. Ces séquences peuvent se propager sous forme de valeur XML vide ou NULL dans le résultat des requêtes selon le contexte d'invocation.

Une conversion explicite en type correct permet aux utilisateurs d'éviter les erreurs statiques même si les erreurs de conversion à l'exécution sont transformées en séquences vides.

Erreurs statiques

Les erreurs statiques sont renvoyées à l'aide du mécanisme d'erreur Transact-SQL. Dans SQL Server, les erreurs de type XQuery sont renvoyées statiquement. Pour plus d'informations, consultez XQuery et le typage statique.

Erreurs dynamiques

Dans XQuery, la plupart des erreurs dynamiques sont mappées à une séquence vide (« () »). Il existe toutefois deux exceptions : les conditions de dépassement dans les fonctions d'agrégation XQuery et les erreurs de validation XML-DML. La plupart des erreurs dynamiques sont mappées à une séquence vide. Sinon, l'exécution de requêtes qui tire parti des index XML peut déclencher des erreurs inattendues. Par conséquent, pour permettre une exécution efficace sans générer d'erreurs inattendues, Moteur de base de données SQL Server mappe les erreurs dynamiques à ().

Si l'erreur dynamique devait se produire dans un prédicat, il est courant que son non-déclenchement épargne la sémantique car () est mappé à False. Toutefois, dans certains cas, le renvoi de () au lieu d'une erreur dynamique peut générer des résultats inattendus. Les exemples suivants illustrent ce point.

Exemple : utilisation de la fonction avg() avec une chaîne

Dans l'exemple suivant, la fonction avg est appelée pour calculer la moyenne des trois valeurs. L'une de ces valeurs est une chaîne. L'instance XML étant, dans ce cas, non typée, toutes les données qu'elle contient sont de type atomique non typé. La fonction avg() convertit ces valeurs au format xs:double puis calcule la moyenne. Toutefois, la valeur "Hello" ne peut pas être convertie au format xs:double et génère une erreur dynamique. Dans ce cas, au lieu de renvoyer une erreur dynamique, la conversion de "Hello" au format xs:double génère une séquence vide. La fonction avg() ignore cette valeur, calcule la moyenne des deux autres valeurs et renvoie 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(//*)')

Exemple: utilisation de la fonction not

Lorsque vous utilisez la fonction not dans un prédicat, tel que /SomeNode[not(Expression)], et que l'expression provoque une erreur dynamique, une séquence vide est renvoyée à la place d'une erreur. L'application de la fonction not() à la séquence vide renvoie True, au lieu d'une erreur.

Exemple: conversion d'une chaîne

Dans l'exemple suivant, la chaîne littérale « NaN » est convertie au format xs:string, puis au format xs:double. Le résultat est un ensemble de lignes vide. Le fait que la chaîne « NaN » ne puisse pas être correctement convertie au format xs:double n'est détecté qu'à l'exécution car elle est d'abord convertie au format xs:string.

DECLARE @x XML
SET @x = ''
SELECT @x.query(' xs:double(xs:string("NaN")) ')
GO

Toutefois, dans cet exemple, une erreur de type statique se produit.

DECLARE @x XML
SET @x = ''
SELECT @x.query(' xs:double("NaN") ')
GO

Limites de l'implémentation

La fonction fn:error() n'est pas prise en charge.