Condividi tramite


Query FOR XML nidificate

In SQL Server 2000 è possibile specificare la clausola FOR XML solo al livello principale di una query SELECT. Il valore XML risultante viene restituito principalmente al client per l'ulteriore elaborazione. Tuttavia, a partire da SQL Server 2005 il tipo di dati xml e la direttiva TYPE nelle query FOR XML abilita all'elaborazione sul server dell'XML restituito dalle query FOR XML.

Elaborazione con variabili di tipo XML

È possibile assegnare il risultato di una query FOR XML a una variabile di tipo xml oppure utilizzare XQuery per eseguire query sul risultato, quindi assegnare tale risultato a una variabile di tipo xml per un'ulteriore elaborazione.

USE AdventureWorks2008R2;
GO
DECLARE @x xml;
SET @x=(SELECT ProductModelID, Name
        FROM Production.ProductModel
        WHERE ProductModelID=122 OR ProductModelID=119
        FOR XML RAW, TYPE);
SELECT @x;

-- Result

--<row ProductModelID="122" Name="All-Purpose Bike Stand" />

--<row ProductModelID="119" Name="Bike Wash" />

Il valore XML restituito nella variabile @x può essere ulteriormente elaborato utilizzando uno dei metodi con tipo di dati xml. Ad esempio, è possibile recuperare il valore dell'attributo ProductModelID utilizzando il metodo value().

DECLARE @i int;
SET @i = (SELECT @x.value('/row[1]/@ProductModelID[1]', 'int'));
SELECT @i;

Nell'esempio seguente il risultato della query FOR XML viene restituito come tipo xml, perché nella clausola FOR XML è specificata la direttiva TYPE.

SELECT ProductModelID, Name
FROM Production.ProductModel
WHERE ProductModelID=119 OR ProductModelID=122
FOR XML RAW, TYPE,ROOT('myRoot');

Risultato:

<myRoot>

<row ProductModelID="122" Name="All-Purpose Bike Stand" />

<row ProductModelID="119" Name="Bike Wash" />

</myRoot>

Poiché il risultato è di tipo xml, è possibile applicare uno dei metodi con tipo di dati xml direttamente al valore XML, come illustrato nella query seguente. Nella query viene utilizzato il metodo query() (tipo di dati xml) per recuperare il primo elemento <row> figlio dell'elemento <myRoot>.

SELECT  (SELECT ProductModelID, Name
         FROM Production.ProductModel
         WHERE ProductModelID=119 OR ProductModelID=122
         FOR XML RAW, TYPE,ROOT('myRoot')).query('/myRoot[1]/row[1]');

Risultato:

<row ProductModelID="122" Name="All-Purpose Bike Stand" />

Restituzione di risultati della query FOR XML interna a query esterne come istanze di tipo XML

È possibile scrivere query FOR XML nidificate in cui il risultato della query interna viene restituito alla query esterna come tipo di dati xml. Esempio:

SELECT Col1, 
       Col2, 
       ( SELECT Col3, Col4 
        FROM  T2
        WHERE T2.Col = T1.Col
        ...
        FOR XML AUTO, TYPE )
FROM T1
WHERE ...
FOR XML AUTO, TYPE;

Dalla query precedente notare quanto segue:

  • Il valore XML generato dalla query FOR XML interna viene aggiunto al valore XML generato dalla query FOR XML esterna.

  • Nella query interna viene specificata la direttiva TYPE. I dati restituiti dalla query interna sono pertanto di tipo xml . Se non si specifica la direttiva TYPE, il risultato della query FOR XML interna viene restituito come nvarchar(max) e i dati XML vengono sostituiti con entità.

Controllo della forma dei dati XML risultanti

Le query FOR XML nidificate consentono di avere un maggior controllo nella definizione della forma dei dati XML risultanti. In SQL Server 2000, per impostazione predefinita, le query in modalità RAW e AUTO generano valori XML incentrati sugli attributi, come illustrato di seguito:

USE AdventureWorks2008R2;
GO
SELECT ProductModelID, Name
FROM Production.ProductModel
WHERE ProductModelID=122 OR ProductModelID=119
FOR XML RAW;

Risultato incentrato sugli attributi:

<row ProductModelID="122" Name="All-Purpose Bike Stand" />

<row ProductModelID="119" Name="Bike Wash" />

In alternativa, specificando la direttiva ELEMENTS, è possibile recuperare tutti i valori XML incentrati sugli elementi, come illustrato di seguito:

SELECT ProductModelID, Name
FROM Production.ProductModel
WHERE ProductModelID=122 OR ProductModelID=119
FOR XML RAW, ELEMENTS ;

Risultato incentrato sugli elementi:

<row>

<ProductModelID>122</ProductModelID>

<Name>All-Purpose Bike Stand</Name>

</row>

<row>

<ProductModelID>119</ProductModelID>

<Name>Bike Wash</Name>

</row>

In SQL Server 2000, pertanto, è necessario scegliere valori XML incentrati sugli attributi o sugli elementi come risultato di una query. Tuttavia, a partire da SQL Server 2005, è possibile utilizzare query FOR XML annidate per costruire valori XML che siano parzialmente incentrati sugli attributi e parzialmente sugli elementi.

Per ulteriori informazioni sulla specifica di valori XML incentrati sugli attributi e sugli elementi con query FOR XML annidate, vedere Query FOR XML e query nidificata FOR XML a confronto e Determinazione della struttura dei valori XML tramite query nidificate FOR XML..

In SQL Server 2000 è possibile creare elementi di pari livello solo formulando query in modalità EXPLICIT, ma ciò può essere eccessivamente complesso. A partire da SQL Server 2005 è possibile generare gerarchie XML che includono elementi di pari livello eseguendo query FOR XML nidificate in modalità AUTO. Per ulteriori informazioni, vedere Generazione di elementi di pari livello tramite query nidificate in modalità AUTO.

Indipendentemente dalla modalità utilizzata, le query FOR XML nidificate consentono un maggior controllo nella definizione della forma dei valori XML risultanti e possono essere utilizzate in sostituzione delle query in modalità EXPLICIT.

Esempi

Negli argomenti seguenti vengono forniti esempi di query FOR XML nidificate.