Partager via


Recommandations pour l'utilisation de la clause FOR XML

La clause FOR XML peut être utilisée dans les requêtes de premier niveau et dans les sous-requêtes. La clause FOR XML de premier niveau ne peut être utilisée que dans l'instruction SELECT. Dans les sous-requêtes, FOR XML peut être utilisée dans les instructions INSERT, UPDATE et DELETE. Elle peut être également utilisée dans les instructions d'assignation. Par exemple :

DECLARE @x xml
SET @x = (SELECT *
FROM Sales.Customer
FOR XML AUTO, TYPE)
SELECT @x

Notez que la directive TYPE renvoie le résultat de la requête en type xml. Si la directive de type n'est pas ajoutée, le résultat de la requête FOR XML est renvoyé en nvarchar(max). Il est ensuite converti en xml et assigné à la variable de type xml.

Son utilisation est exclue dans les cas suivants :

  • La clause FOR XML n'est pas valide en cas de sélection comportant une clause COMPUTE BY ou FOR BROWSE. Par exemple, la syntaxe suivante générera une erreur :

    SELECT TOP 5 SalesOrderID, UnitPrice 
    FROM Sales.SalesOrderDetail 
    ORDER BY SalesOrderID COMPUTE SUM(UnitPrice) BY SalesOrderID
    FOR XML AUTO
    
  • Une clause FOR XML de premier niveau sans directive TYPE ne peut pas être utilisée avec les curseurs.

  • Quand une instruction SELECT avec une clause FOR XML spécifie un nom en quatre parties dans la requête, le nom du serveur n'est pas renvoyé dans le document XML résultant quand la requête est exécutée sur l'ordinateur local. Cependant, le nom du serveur est renvoyé sous forme de nom en quatre parties quand la requête s'exécute sur un serveur.
    Par exemple, envisagez la requête suivante :

    SELECT TOP 1 LastName
    FROM ServerName.AdventureWorks.Person.Contact
    FOR XML AUTO
    

    Quand ServerName est un serveur local, la requête renvoie :

    <AdventureWorks.Person.Contact LastName="Achong" />
    

    Quand ServerName est un serveur réseau, la requête renvoie :

    <ServerName.AdventureWorks.Person.Contact LastName="Achong" />
    

    Cette ambiguïté peut être levée à condition de spécifier cet alias :

    SELECT TOP 1 LastName
    FROM ServerName.AdventureWorks.Person.Contact x
    FOR XML AUTO 
    

    Cette requête donne le résultat suivant :

    <x LastName="Achong"/>
    

En outre, les noms SQL Server contenant des caractères non valides pour les noms XML (comme les espaces) sont convertis en noms XML de telle façon que les caractères non valides soient convertis en codes d'entités numériques d'échappement.

Seuls deux caractères non alphabétiques sont autorisés au début d'un nom XML : les deux-points (:) et le trait de soulignement (_). Dans la mesure où les deux-points (:) sont déjà réservés aux espaces de noms, le trait de soulignement (_) est utilisé comme caractère d'échappement. Les règles d'échappement utilisées pour le codage sont les suivantes :

  • Tout caractère UCS-2 qui n'est pas un caractère valide pour un nom XML (selon la spécification XML 1.0), est placé en mode échappement sous la forme _xHHHH_. La chaîne HHHH désigne le code hexadécimal UCS-2 à quatre chiffres du caractère dans l'ordre du bit le plus significatif en premier. Par exemple, le nom de la table Order Details est codé sous la forme Order_x0020_Details.

  • Les caractères qui n'entrent pas dans le domaine UCS-2 (les ajouts UCS-4 correspondant à la plage comprise entre U+00010000 et U+0010FFFF) sont codés sous la forme _xHHHHHHHH_, où HHHHHHHH représente le code UCS-4 hexadécimal à huit chiffres du caractère, en cas d'utilisation du mode de compatibilité ascendante avec SQL Server 2000. Dans tous les autres cas, les caractères sont codés sous la forme _xHHHHHH_ de façon à respecter la norme SQL-2003.

  • Le caractère de soulignement n'a pas besoin d'être en mode échappement sauf s'il est suivi du caractère x. Par exemple, le nom de la table Order_Details n'est pas codé.

  • Dans les identificateurs, les deux-points (:) ne sont pas placés en mode échappement pour que les noms d'élément ou d'attribut des espaces de noms puissent être générés par la requête FOR XML. Par exemple, la requête suivante génère un attribut d'espace de noms comportant deux-points (:) dans le nom :

    SELECT 'namespace-urn' as 'xmlns:namespace', 
     1 as 'namespace:a' 
    FOR XML RAW
    

    La requête produit le résultat suivant :

    <row xmlns:namespace="namespace-urn" namespace:a="1"/>
    

    Notez qu'il est quand même préférable d'utiliser WITH XMLNAMESPACES pour ajouter des espaces de noms XML.

  • Dans une requête SELECT, la conversion d'une colonne en type de données BLOB en fait une entité temporaire puisqu'elle perd les noms de table et de colonne qui lui sont associés. De ce fait, les requêtes exprimées en mode AUTO génèrent une erreur car elles ne savent pas où placer cette valeur dans la hiérarchie XML. Par exemple :

    CREATE TABLE MyTable (Col1 int PRIMARY KEY, Col2 binary)
    INSERT INTO MyTable VALUES (1, 0x7)
    

    Cette requête produit une erreur en raison de la conversion en un type de données BLOB.

    SELECT Col1,
    CAST(Col2 as image) as Col2
    FROM MyTable
    FOR XML AUTO
    

    La solution consiste à ajouter l'option BINARY BASE64 dans la clause FOR XML. Si vous supprimez la conversion, la requête produit les résultats escomptés :

    SELECT Col1,
    Col2
    FROM MyTable
    FOR XML AUTO
    

    Voici le jeu de résultats obtenu :

    <MyTable Col1="1" Col2="dbobject/MyTable[@Col1='1']/@Col2" />
    
  • Dans SQL Server 2000, le résultat d'une clause FOR XML peut contenir des caractères XML non valides. Par exemple, la valeur hexadécimale 7 est utilisée comme caractère de format, mais elle n'est, en principe, pas visible comme texte dans la sortie. SQL Server 2005 utilise désormais le codage d'entité de ces caractères lorsqu'ils sont renvoyés avec des requêtes FOR XML ne faisant pas intervenir la directive TYPE.
    Bien que les analyseurs XML 1.0 génèrent des erreurs d'analyse, que ces caractères soient ou non codés sous forme d'entité, le codage d'entité est plus en conformité avec XML 1.1. Le codage d'entité est aussi en meilleure adéquation avec les futures versions de la norme XML. De plus, il facilite le débogage puisque le point de code du caractère incorrect est visible.
    Pour les utilisateurs d'outils XML, il n'existe aucun moyen de contourner le problème puisque l'analyseur XML échouera quoi qu'il arrive au point où se présentent les caractères non valides dans le flux de données. Si vous utilisez des outils non XML, cette modification risque de vous imposer la mise à jour de votre logique de programmation afin de rechercher ces caractères sous la forme de leurs codes d'entité.

  • Dans SQL Server 2005, les caractères d'espace suivants sont désormais codés différemment dans les requêtes FOR XML afin de les garder présents tout au long des va-et-vient :

    • Dans le contenu et les attributs d'élément : hex(0D) (retour chariot)
    • Dans le contenu d'attribut : hex(09) (tabulation), hex(0A) (saut de ligne)

    Ce nouveau codage risque d'avoir une incidence sur votre application si cette dernière a été conçue à l'origine pour traiter des sorties SQL Server 2000 dans lesquelles ces caractères étaient normalisés. Dans SQL Server 2005, les sorties conservent désormais ces caractères et un analyseur n'aura plus à les normaliser.

Voir aussi

Référence

Construction de code XML à l'aide de FOR XML

Autres ressources

SELECT (Transact-SQL)

Aide et Informations

Assistance sur SQL Server 2005