Directive TYPE dans les requêtes FOR XML

Dans SQL Server 2000, le résultat d'une requête FOR XML est toujours directement renvoyé au client sous forme de texte. Grâce à la prise en charge du type de données xml dans SQL Server 2005, vous pouvez éventuellement demander que le résultat d'une requête FOR XML soit renvoyé en tant que type de données xml en spécifiant la directive TYPE. Cela vous permet de traiter le résultat d'une requête FOR XML sur le serveur. Par exemple, vous pouvez spécifier une requête XQuery par rapport au résultat, affecter le résultat à une variable de type xml ou écrire des requêtes FOR XML imbriquées.

ms190025.note(fr-fr,SQL.90).gifRemarque :
SQL Server renvoie des données d'instance de type de données XML au client comme résultat de différentes constructions de serveur telles que des requêtes FOR XML qui utilisent la directive TYPE ou dans lesquelles le type de données xml permet de renvoyer des valeurs de données d'instance XML à partir de paramètres de sortie et de colonnes de table SQL. Dans le code de l'application cliente, le fournisseur ADO.NET demande à ce que ces informations de type de données XML soient envoyées dans un codage binaire à partir du serveur. Toutefois, si vous utilisez FOR XML sans la directive TYPE, les données XML reviennent en tant que type chaîne. Dans tous les cas, le fournisseur client est toujours en mesure de gérer n'importe quelle forme du document XML.

Exemples

Les exemples suivants illustrent l'utilisation de la requête FOR XML.

A. Extraction des résultats de la requête FOR XML en tant que type xml

La requête suivante extrait des informations de contact client de la table Contacts. Étant donné que la directive TYPE est spécifiée sous la forme FOR XML, le résultat est renvoyé en tant que type xml.

SELECT ContactID, FirstName, LastName, Phone
FROM Person.Contact
ORDER BY ContactID
FOR XML AUTO, TYPE

Voici le résultat partiel :

<Contact ContactID="1" FirstName="Syed" LastName="Abbas" 
         Phone="398-555-0132"/>
<Contact ContactID="2" FirstName="Catherine" LastName="Abel" 
         Phone="747-555-0171"/>
...

B. Affectation des résultats de la requête FOR XML à une variable de type xml

Dans l'exemple suivant, un résultat FOR XML est affecté à une variable de type xml, @x. La requête extrait les informations de contact, telles que l'identificateur (ContactID), le prénom (FirstName), le nom (LastName) et des numéros de téléphone supplémentaires, de la colonne AdditionalContactInfo de type xml. Étant donné que la clause FOR XML spécifie la directive TYPE, le document XML est renvoyé en tant que type xml et affecté à une variable.

DECLARE @x XML
SET @x = (
   SELECT ContactID, 
          FirstName, 
          LastName, 
          AdditionalContactInfo.query('
declare namespace aci="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactInfo";
declare namespace act="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes";
              //act:telephoneNumber/act:number') as MorePhoneNumbers
   FROM Person.Contact
   FOR XML AUTO, TYPE)
SELECT @x
GO

C. Interrogation des résultats d'une requête FOR XML

Les requêtes FOR XML renvoient des données XML. Par conséquent, vous pouvez appliquer des méthodes de type xml, telles que query() et value(), au résultat XML renvoyé par des requêtes FOR XML.

Dans la requête suivante, la méthode query() du type de données xml permet d'interroger le résultat de la requête FOR XML. Pour plus d'informations, consultez Méthode query() (type de données xml).

SELECT (SELECT ContactID, FirstName, LastName, AdditionalContactInfo.query('
declare namespace aci="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactInfo";
declare namespace act="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes";
 //act:telephoneNumber/act:number
') as PhoneNumbers
FROM Person.Contact
FOR XML AUTO, TYPE).query('/Person.Contact[1]')

La requête SELECT … FOR XML interne renvoie un résultat au type xml duquel la requête SELECT externe applique la méthode query(). Notez la directive TYPE spécifiée.

Voici le jeu de résultats obtenu :

<Person.Contact ContactID="1" FirstName="Gustavo" LastName="Achong">
  <PhoneNumbers>
    <act:number xmlns:act="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes">111-111-1111</act:number>
    <act:number xmlns:act="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes">112-111-1111</act:number>
  </PhoneNumbers>
</Person.Contact>

Dans la requête suivante, la méthode value() du type de données xml permet d'extraire une valeur du résultat XML renvoyé par la requête SELECT…FOR XML. Pour plus d'informations, consultez value(), méthode (Type de données xml).

declare @FirstPhoneFromAdditionalContactInfo varchar(40);
SELECT @FirstPhoneFromAdditionalContactInfo = 
 ( SELECT ContactID, FirstName, LastName, AdditionalContactInfo.query('
declare namespace aci="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactInfo";
declare namespace act="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes";

   //act:telephoneNumber/act:number
   ') as PhoneNumbers
   FROM Person.Contact Contact
   FOR XML AUTO, TYPE).value('
declare namespace act="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes";
  /Contact[@ContactID="1"][1]/PhoneNumbers[1]/act:number[1]', 'varchar(40)'
 )
select @FirstPhoneFromAdditionalContactInfo

L'expression de chemin d'accès XQuery dans la méthode value() extrait le premier numéro de téléphone d'un contact client dont ContactID a pour valeur 1.

ms190025.note(fr-fr,SQL.90).gifRemarque :
Si la directive TYPE n'est pas spécifiée, le résultat de la requête FOR XML est renvoyé en tant que type nvarchar(max).

D. Utilisation des résultats de la requête FOR XML dans INSERT, UPDATE et DELETE (Transact-SQL DML)

L'exemple suivant montre comment des requêtes FOR XML peuvent être utilisées dans des instructions DML (Data Manipulation Language). Dans l'exemple, la requête FOR XML renvoie une instance de type xml. L'instruction INSERT insère ce document XML dans une table.

CREATE TABLE T1(intCol int, XmlCol xml)
go
INSERT INTO T1 
VALUES(1, '<Root><ProductDescription ProductModelID="1" /></Root>')
go

CREATE TABLE T2(XmlCol xml)
go
INSERT INTO T2(XmlCol) 
SELECT (SELECT XmlCol.query('/Root') 
        FROM T1 
        FOR XML AUTO,TYPE) 
go