Condividi tramite


Direttiva TYPE in query FOR XML

In SQL Server 2000 il risultato di una query FOR XML è sempre restituito direttamente al client in formato testuale. Grazie al supporto per il tipo di dati xml disponibile in SQL Server 2005 è possibile richiedere facoltativamente che il risultato di una query FOR XML venga restituito come tipo di dati xml, specificando la direttiva TYPE. In questo modo è possibile elaborare il risultato di una query FOR XML nel server. Ad esempio, è possibile specificare un'espressione XQuery per la query FOR XML , assegnare il risultato a una variabile di tipo xml, oppure scrivere query FOR XML nidificate.

[!NOTA] SQL Server restituisce dati di istanza di tipo XML al client come risultato di diversi costrutti server, ad esempio query FOR XML che utilizzano la direttiva TYPE, o in cui il tipo di dati xml viene utilizzato per la restituzione di valori dei dati dell'istanza XML da colonne di tabella e parametri di output SQL. Nel codice delle applicazioni client, il provider ADO.NET richiede che i dati di tipo XML vengano inviati dal server in codifica binaria. Se tuttavia si utilizza FOR XML senza la direttiva TYPE, i dati XML vengono restituiti come tipo stringa. Il provider del client è in ogni caso in grado di gestire entrambi i formati del codice XML.

Esempi

Nell'esempio seguente viene illustrato l'utilizzo della query FOR XML.

A. Recupero dei risultati di una query FOR XML come tipo xml

La query seguente recupera le informazioni di contatto del cliente dalla tabella Contacts. Poiché in FOR XML è specificata la direttiva TYPE, il risultato viene restituito come tipo xml.

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

Risultato parziale:

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

B. Assegnazione dei risultati di una query FOR XML a una variabile di tipo xml

Nell'esempio seguente il risultato di una query FOR XML viene assegnato a una variabile di tipo xml, @x. La query recupera le informazioni di contatto, ad esempio, ContactID, FirstName, LastName e i numeri di telefono aggiuntivi dalla colonna AdditionalContactInfo di tipo xml. Poiché la clausola FOR XML specifica la direttiva TYPE, il codice XML viene restituito come tipo xml e assegnato a una variabile.

DECLARE @x XML
SET @x = (
   SELECT ContactID, 
          FirstName, 
          LastName, 
          AdditionalContactInfo.query('
declare namespace aci="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactInfo";
declare namespace act="https://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. Esecuzione di una query sui risultati di una query FOR XML

La query FOR XML restituisce codice XML. È pertanto possibile applicare al risultato XML restituito dalle query FOR XML i metodi con tipo xml, ad esempio query() e value().

Nella query seguente il metodo query() del tipo di dati xml viene utilizzato per l'esecuzione di una query sui risultati della query FOR XML. Per ulteriori informazioni, vedere Metodo query() con tipo di dati XML.

SELECT (SELECT ContactID, FirstName, LastName, AdditionalContactInfo.query('
declare namespace aci="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactInfo";
declare namespace act="https://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 query interna SELECT … FOR XML restituisce un risultato di tipo xml al quale la query SELECT esterna applica il metodo query() al tipo xml. Si noti la direttiva TYPE specificata.

Risultato:

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

Nella query seguente, il metodo value() con tipo di dati xml viene utilizzato per recuperare un valore dal risultato XML restituito dalla query SELECT…FOR XML. Per ulteriori informazioni, vedere Metodo value() (tipo di dati xml).

declare @FirstPhoneFromAdditionalContactInfo varchar(40);
SELECT @FirstPhoneFromAdditionalContactInfo = 
 ( SELECT ContactID, FirstName, LastName, AdditionalContactInfo.query('
declare namespace aci="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactInfo";
declare namespace act="https://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="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes";
  /Contact[@ContactID="1"][1]/PhoneNumbers[1]/act:number[1]', 'varchar(40)'
 )
select @FirstPhoneFromAdditionalContactInfo

L'espressione di percorso XQuery nel metodo value() recupera il primo numero di telefono di un cliente il cui ContactID è 1.

[!NOTA] Se non si specifica la direttiva TYPE, il risultato della query FOR XML viene restituito come tipo nvarchar(max).

D. Utilizzo dei risultati di query FOR XML in istruzioni INSERT, UPDATE e DELETE (DML Transact-SQL)

Nell'esempio seguente viene illustrato l'utilizzo delle query FOR XML nelle istruzioni DML (Data Manipulation Language). Nell'esempio, la query FOR XML restituisce un'istanza di tipo xml. L'istruzione INSERT inserisce il codice XML in una tabella.

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