Directiva TYPE en consultas FOR XML
En SQL Server 2000, el resultado de una consulta FOR XML se devuelve siempre directamente al cliente en forma de texto. A partir de SQL Server 2005, SQL Server es compatible con el tipo de datos xml, lo que ofrece la opción de solicitar la devolución del resultado de una consulta FOR XML como tipo de datos xml especificando la directiva TYPE. Esto permite procesar el resultado de una consulta FOR XML en el servidor. Por ejemplo, puede especificar una XQuery en el mismo, asignar el resultado a una variable de tipo xml o escribir consultas FOR XML anidadas.
Nota
SQL Server devuelve al cliente datos de instancia de tipo XML como resultado de distintas construcciones de servidor, como por ejemplo consultas FOR XML que utilizan la directiva TYPE o en las que se utiliza el tipo de datos xml para devolver valores de datos de instancia XML procedentes de columnas de tablas SQL y parámetros de salida. En el código de las aplicaciones cliente, el proveedor ADO.NET solicita que se envíe esta información de tipo de datos XML con una codificación binaria desde el servidor. Sin embargo, si utiliza FOR XML sin la directiva TYPE, se devolverán los datos XML en forma de cadena. En cualquier caso, el proveedor del cliente siempre podrá controlar cualquier formato de tipo XML. Tenga en cuenta que la cláusula FOR XML de nivel superior sin la directiva TYPE no puede utilizarse con cursores.
Ejemplos
En los ejemplos siguientes se muestra el uso de la directiva TYPE con consultas FOR XML.
Recuperar resultados de consultas FOR XML en forma de xml
En la consulta siguiente se recupera información de contacto de clientes de la tabla Contacts. Puesto que se especifica la directiva TYPE en FOR XML, el resultado se devuelve como de tipo xml.
USE AdventureWorks2008R2;
Go
SELECT BusinessEntityID, FirstName, LastName
FROM Person.Person
ORDER BY BusinessEntityID
FOR XML AUTO, TYPE;
Este es el resultado parcial:
<Person.Person BusinessEntityID="1" FirstName="Ken" LastName="Sánchez"/>
<Person.Person BusinessEntityID="2" FirstName="Terri" LastName="Duffy"/>
...
Asignar resultados de consultas FOR XML a una variable de tipo xml
En el ejemplo siguiente, se asigna un resultado de FOR XML a una variable de tipo xml, @x. La consulta recupera información de contacto, como BusinessEntityID, FirstName o LastName, y números de teléfono adicionales, de la columna AdditionalContactInfo de xmlTYPE. Puesto que la cláusula FOR XML especifica la directiva TYPE, se devuelve XML en forma de tipo xml y se asigna a una variable.
USE AdventureWorks2008R2;
GO
DECLARE @x xml;
SET @x = (
SELECT BusinessEntityID,
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.Person
FOR XML AUTO, TYPE);
SELECT @x;
GO
Consultar los resultados de una consulta FOR XML
Las consultas FOR XML devuelven XML. Por tanto, puede aplicar métodos del tipo xml, como query() y value(), al resultado XML devuelto por las consultas FOR XML.
En la consulta siguiente, se utiliza el método query() del tipo de datos xml para consultar el resultado de la consulta FOR XML. Para obtener más información, vea query() (método de tipo de datos xml).
USE AdventureWorks2008R2;
GO
SELECT (SELECT BusinessEntityID, 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.Person
FOR XML AUTO, TYPE).query('/Person.Person[1]');
La consulta SELECT … FOR XML interna devuelve un resultado de tipo xml al que la instrucción SELECT externa aplica el método query() al tipo xml. Observe la directiva TYPE especificada.
El resultado es el siguiente:
<Person.Person BusinessEntityID="1" FirstName="Ken" LastName="Sánchez">
<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.Person>
En la consulta siguiente, el método value() del tipo de datos xml se utiliza para recuperar un valor del resultado XML devuelto por la consulta SELECT…FOR XML. Para obtener más información, vea value() (método del tipo de datos xml).
USE AdventureWorks2008R2;
GO
DECLARE @FirstPhoneFromAdditionalContactInfo varchar(40);
SELECT @FirstPhoneFromAdditionalContactInfo =
( SELECT BusinessEntityID, 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.Person Contact
FOR XML AUTO, TYPE).value('
declare namespace act="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes";
/Contact[@BusinessEntityID="1"][1]/PhoneNumbers[1]/act:number[1]', 'varchar(40)'
)
SELECT @FirstPhoneFromAdditionalContactInfo;
La expresión de ruta de acceso XQuery del método value() recupera el primer número de teléfono de un contacto de cliente cuyo BusinessEntityID es 1.
Nota
Si no se especifica la directiva TYPE, se devolverá el resultado de la consulta FOR XML con el tipo nvarchar(max).
Utilizar resultados de consultas FOR XML en INSERT, UPDATE y DELETE (DML de Transact-SQL)
En el ejemplo siguiente se muestra el modo en el que se pueden utilizar las consultas FOR XML en instrucciones del lenguaje de manipulación de datos (DML). En este ejemplo, FOR XML devuelve una instancia del tipo xml. La instrucción INSERT inserta esta instancia de tipo XML en una tabla.
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