Sie sind auf Seite 1von 32

XML

Mtodos Value()
Realiza una consulta XQuery en datos XML y devuelve un valor de tipo SQL. Este mtodo devuelve un valor escalar. Normalmente, este mtodo se utiliza para extraer un valor de una instancia XML almacenada en una columna, parmetro o variable de tipo xml. De esta manera, se pueden especificar consultas SELECT que combinen o comparen datos XML con datos de columnas que no son XML. El mtodo value() utiliza el operador CONVERT de Transact-SQL de manera implcita e intenta convertir el resultado de la expresin XQuery, la representacin de cadena serializada, del tipo XSD al tipo SQL correspondiente especificado por la conversin Transact-SQL. Para obtener ms informacin acerca de las reglas de conversin de tipos de CONVERT, vea CAST y CONVERT (Transact-SQL)

Sintaxis Value(XQuery, SQLType)

Argumentos XQUery: Es la expresin XQuery, un literal de cadena, que recupera los datos de la instancia XML. La expresin XQuery debe devolver un valor como mximo. En caso contrario, se devuelve un error.

SQLType: Es el tipo SQL preferido, un literal de cadena, que se devuelve. El tipo de valor devuelto de este mtodo coincide con el parmetro SQLType. SQLType no puede ser un tipo de datos xml, un tipo definido por el usuario de Common Language Runtime (CLR), image, text, ntext o un tipo de datos sql_variant. SQLType puede ser un tipo de datos definido por el usuario SQL.

Ejemplos

-- Generar select normal con todos los valores del xml, con su nombre de columna respectivo (uso de ".value()") set @w = '<VER> <ADJ Op="I"> <IDVersionInterna>1</IDVersionInterna> <IDAdjunto>1</IDAdjunto> <Producto>MF_CLIENTE</Producto> <Tipo>Base</Tipo> <Nombre>Base Maestro</Nombre> <Descripcion>Contiene informacion para aplicacione en clientes</Descripcion> </ADJ> </VER>' --TIPS: FIJARSE EN LA TABLA DONDE SE VAN A ALMACENAR EL TIPO EN COMO ESTAN DECLARADOS LOS DATOS. ES ESE TIPO EL QUE MANDA EL DE LA TABLA FINAL --atributo se leen con @ no asi los elementos SELECT @w.value('(/VER/ADJ/@Op)[1]','char(1)') as Op , @w.value('(/VER/ADJ/IDVersionInterna)[1]','int') as IDVersionInterna , @w.value('(/VER/ADJ/IDAdjunto)[1]','int')AS IDAdjunto, @w.value('(/VER/ADJ/Producto)[1]','char(10)')AS Producto, @w.value('(/VER/ADJ/Tipo)[1]','char(10)')AS Tipo, @w.value('(/VER/ADJ/Nombre)[1]','char(20)')AS Nombre, @w.value('(/VER/ADJ/Descripcion)[1]','char(80)')AS Descripcion Resultado

Query()
Especifica una expresin XQuery para una instancia de tipo de datos xml. El resultado es de tipo xml. El mtodo devuelve una instancia XML sin tipo. Otra definicin encontrada en internet podra ser la siguiente: se utiliza para especificar una consulta en una instancia XML que se almacena en una variable o columna de tipo xml

Sintaxis Query(XQuery)

Argumentos XQuery: Es una cadena, una expresin XQuery, que consulta nodos XML como, por ejemplo, elementos y atributos, en una instancia XML.

Ejemplos

-- Generar select normal con todos los valores del tag TipoVersion, adems del xml de los comentarios, todo con su nombre de columna respectivo (uso de ".value()" y ".query()") DECLARE @x xml set @x = '<COM> <TipoVersion IDVersion="7">Interno</TipoVersion> <Comentarios> <Comentario IDUsuario="1" >se debe apurar el cierre de la version</Comentario> </Comentarios> </COM>' SELECT @x.value('(/COM/TipoVersion/@IDVersion)[1]','int') AS TipoVersion, @x.value('(/COM/TipoVersion)[1]','varchar(10)') as IDVersion, @x.value('(/COM/Comentarios/Comentario/@IDUsuario)[1]','int') AS IDUsuario, @x.query('/COM/Comentarios') as Comentario

Resultado

Nodes()
El mtodo nodes() es muy til si desea dividir una instancia de tipo de datos xml en datos relacionales. Permite identificar nodos que se asignarn a una fila nueva. Cada instancia de tipo de datos xml tiene un nodo de contexto proporcionado de manera implcita. En el caso de la instancia XML almacenada en una columna o variable, ste es el nodo de documento. El nodo de documento es el nodo implcito situado en la parte superior de cada instancia de tipo de datos xml. El resultado del mtodo nodes() es un conjunto de datos que contiene copias lgicas de las instancias XML originales. En estas copias lgicas, el nodo de contexto de cada instancia de fila se establece en uno de los nodos identificados con la expresin de consulta, de manera que las consultas posteriores pueden navegar de forma relativa hasta estos nodos de contexto. Puede recuperar varios valores del conjunto de filas. Por ejemplo, puede aplicar el mtodo value() al conjunto de filas devuelto por nodes() y recuperar varios valores de la instancia XML original. Tenga en cuenta que el mtodo value(), cuando se aplica a la instancia XML, devuelve slo un valor. Sintaxis Nodes(Xquery) as table(column)

Argumentos XQuery: Es un literal de cadena, una expresin XQuery. Si la expresin de consulta construye nodos, stos se exponen en el conjunto de filas resultante. Si la expresin de consulta da lugar a una secuencia vaca, el conjunto de filas estar vaco. Si la expresin de consulta da lugar estticamente a una secuencia que contiene valores atmicos en lugar de nodos, se produce un error esttico. Table(column): Es el nombre de tabla y el nombre de columna del conjunto de filas resultante.

Ejemplo

-- Generar select normal con los valores contenidos en el xml, todo con su nombre correspondiente (uso de ".nodes()") DECLARE @y xml set @y = '<Festivos> <Ao A="2008"> <Mes M="11" Nombre="Noviembre"/> <Mes M="12" Nombre="Diciembre"/> </Ao> <Ao A="2009"> <Mes M="1" Nombre="Enero"/> </Ao> </Festivos>' (../@A): Hace posible que muestre ao 2008 y 2009 donde corresponde para cada mes. Si se deja especificada la ruta mostrar solo o un ao o el otro SELECT T.c.value('(../@A)[1]','int') AS Ao, T.c.value('(@M)[1]','int') AS mes, T.c.value('(@Nombre)[1]','CHAR(20)') AS Nombre FROM @y.nodes('/Festivos/Ao/Mes') T(c)

Resultado

exist()
Devuelve un bit como resultado de ejecutar una consulta XQuery sobre un dato XML, de tal modo, que los resultados posibles son: 1, si el resultado de la consulta XQuery NO es vaco. 0, si el resultado de la consulta XQuery es vaco. NULL, si el dato XML que se est consultando, es NULL.

y y y

El mtodo XML exist() suele utilizarse en la clusula WHERE de consultas SQL. Sintaxis:

exist(XQuery) XQuery : Es una expresin XQuery, un literal de cadena.

Otra forma de sintaxis puede ser la siguiente que est siendo utilizado en el ejemplo 2:

SELECT ProductName FROM Products WHERE XmlProduct.exist( '/root[@Stock=sql:column("Stock")]') = 1

El mtodo exist() devuelve 1 para la expresin XQuery que devuelve un resultado no vaco. Si se especifican las funciones true() o false() dentro del mtodo exist(), el mtodo exist() devolver 1, porque las funciones true() y false() devuelven los valores booleanos True y False respectivamente. En otras palabras, devuelven un resultado no vaco. Por tanto, exist() devolver 1 (True), como se muestra en el ejemplo siguiente: Ejemplo 1

declare @x xml set @x='' select @x.exist('true()')

Ejemplo 2 Conectndose a la BD de Learning se puede consultar la tabla mtPRO_proyecto ah ejecutar una query que liste todos los productos que contengan asociado MB la lista de productos est asociado al campo tbpr_Productos que es un XML. En el campo tbpr_Productos el XML est de la siguiente manera:

<PRO> <Producto Nombre="MB" /> </PRO>


Por lo tanto para recuperar ese dato la query indicada sera asi:

SELECT tbpr_Productos from mtPRO_proyecto where tbpr_Productos.exist('/PRO/Producto[@Nombre = "MB"]') = 1


Ejemplo 3 Este ejemplo al ejecutarlo trae como resultado un boolean. Que traer un 1 indicando que dentro del XML si hay dentro del tag Name un nombre que es igual a John

declare @x xml set @x = '<Person><Name>John</Name><Age>24</Age></Person>' select @x.exist('/Person/Name[.="John"]')

Otros ejemplos de querys con sacados desde internet:

select customer_info from customers where customer_info.exist('/Customer/Name = "John"') = 1 select customer_info from customers where customer_info.exist('/Customer/Name[. = "John"]') = 1 --QUERY HECHA PARA CUANDO EL ATRIBUTO ESTA EN EL MEDIO DEL TAG select customer_info from customers where customer_info.exist('/Customer/Name/text()[. = "John"]') = 1

column()
Se puede usar la funcin sql:column() cuando se utilicen mtodos de tipo de datos XML para exponer un valor relacional dentro de XQuery.

Ejemplo 1 Dentro de el @x.query se puede declarar de manera diferente la raz <Agent> y sus hojas <AgentID>, <Fname> y <SSN> ponerle otros nombres y simplemente tendrn nombres diferentes cuando retorne el resultado de los datos. Lo que NO PUEDE CAMBIAR es el valor que est dentro de el (AgentID), (Fname) y (SSN) porque hace referencia al nombre de la columna de la tabla. Si por error es mal escrito retornar un error como el siguiente:
Msg 207, Level 16, State 1, Line 3 Invalid column name 'AgntID'

DECLARE @x XML SET @x = '' SELECT @x.query('<Agent> <AgentID> "{sql:column("AgentID")}"</AgentID> <Fname> "{sql:column("Fname")}"</Fname> <SSN> "{sql:column("SSN")}"</SSN> </Agent>') FROM dbo.agent
Ejemplo 2

DECLARE @a XML SET @a = '' SELECT @a.query(' <Config> <tbco_IDConfig> "{sql:column("tbco_IDConfig")}"</tbco_IDConfig> <tbco_Ubicacion> "{sql:column("tbco_Ubicacion")}"</tbco_Ubicacion> <tbco_Descripciont> "{sql:column("tbco_Descripciont")}" </tbco_Descripciont> <Personalizado> "{sql:column("Personalizado")}"</Personalizado> </Config>') FROM dbo.mbGLO_Config

variable()
Permite utilizar el valor de una variable de SQL en la expresin XQuery o XML Asimismo, este enlace es de slo lectura. En otras palabras, no se pueden escribir datos en las columnas que utilicen estas funciones. Por ejemplo, no se permite sql:variable("@x")="alguna expresin". Ejemplo 1

DECLARE @b VARCHAR(10) DECLARE @c VARCHAR(10) SET @b = 'DI' SET @c = 'PDF' SELECT * FROM mtPRO_proyecto WHERE tbpr_productos.exist('PRO/Producto [@Nombre = sql:variable("@b")]')=1 AND tbpr_productos.exist('PRO/Producto [@Nombre = sql:variable("@c")]')=1
Ejemplo 2

DECLARE @d VARCHAR(max) SET @d = '30' SELECT * FROM dbo.mtLOG_Log where tblo_Detalle.exist('DES/Datos [@Horas = sql:variable("@d")]')=1

Ejemplo 3

DECLARE SET SELECT FROM WHERE

@a varchar(20) @a = '6' tblo_detalle dbo.mtLOG_Log tblo_Detalle.exist ('/DES/Datos/@Autor[. = sql:variable("@a")]') = 1

modify()
Modifica el contenido de un documento XML. Utilice este mtodo para modificar el contenido de una columna o variable de tipo xml. Este mtodo toma una instruccin XML DML para insertar, actualizar o eliminar nodos a partir de datos XML. Para mayor detalle es tambin utilizado con las funciones insert (XML DML), delete (XML DML) y replace value of (XML DML)

insert()
Inserta uno o ms nodos identificados como nodos secundarios o del mismo nivel que el nodo identificado Ejemplo 1

DECLARE @x xml set @x = '<COM> <TipoVersion IDVersion="7">Interno</TipoVersion> <Comentarios> <Comentario IDUsuario="1" >se debe apurar el cierre de la version</Comentario> </Comentarios> </COM>' SET @x.modify(' insert<Mas_Comentarios>este es otro comentario</Mas_Comentarios> into(/COM/Comentarios)[1]') SELECT @x
Resultado

<COM> <TipoVersion IDVersion="7">Interno</TipoVersion> <Comentarios> <Comentario IDUsuario="1">se debe apurar el cierre de la version</Comentario> <Mas_Comentarios>este es otro comentario</Mas_Comentarios> </Comentarios> </COM>

Ejemplo 2 Insert doble de nodos

DECLARE @x xml set @x = '<COM> <TipoVersion IDVersion="7">Interno</TipoVersion> <Comentarios> <Comentario IDUsuario="1" >se debe apurar el cierre de la version</Comentario> <Mas_Comentarios>este es otro comentario</Mas_Comentarios> </Comentarios> </COM>' SET @x.modify(' insert<ID IDNumber="8">ID 8</ID> as last into(/COM)[1]'); SET @x.modify(' insert<ID IDNumber="9">ID 9</ID>as first into(/COM)[1]') SELECT @x

Resultado

<COM> <ID IDNumber="9">ID 9</ID> <TipoVersion IDVersion="7">Interno</TipoVersion> <Comentarios> <Comentario IDUsuario="1">se debe apurar el cierre de la version</Comentario> <Mas_Comentarios>este es otro comentario</Mas_Comentarios> </Comentarios> <ID IDNumber="8">ID 8</ID> </COM>
Ejemplo 3 Inserta un nodo de texto al inicio del XML

DECLARE @x xml set @x = '<COM> <ID IDNumber="9">ID 9</ID> <TipoVersion IDVersion="7">Interno</TipoVersion> <Comentarios> <Comentario IDUsuario="1">se debe apurar el cierre de la version</Comentario> <Mas_Comentarios>este es otro comentario</Mas_Comentarios> </Comentarios> <ID IDNumber="8">ID 8</ID> </COM>' SET @x.modify(' insert text {"Texto insertado correctamente"} as first into (/COM)[1]') SELECT @x

Resultado Parcial

<COM>Texto insertado correctamente<ID IDNumber="9">ID 9</ID><TipoVersion IDVersion="7">Interno</TipoVersion><Coment

Ejemplo 4 Inserta atributos en un elemento. Dentro del tag TipoVersion inserta el atributo PPP con valor igual a 666 (PPP= 666)

DECLARE @x xml set @x = '<COM> <TipoVersion IDVersion="7">Interno</TipoVersion> <Comentarios> <Comentario IDUsuario="1" >se debe apurar el cierre de la version</Comentario> </Comentarios> </COM>' SET @x.modify(' insert attribute PPP {"666"} into (/COM/TipoVersion[@IDVersion=7])[1]') SELECT @x
Resultado

<COM> <TipoVersion IDVersion="7" PPP="666">Interno</TipoVersion> <Comentarios> <Comentario IDUsuario="1">se debe apurar el cierre de la version</Comentario> </Comentarios> </COM>

delete()
Elimina nodos de una instancia XML.

Ejemplo 1

--borra un atributo de ID 9 DECLARE @x xml set @x = '<COM> <ID IDNumber="9">ID 9</ID> <TipoVersion IDVersion="7">Interno</TipoVersion> <Comentarios> <Comentario IDUsuario="1">se debe apurar el cierre de la version</Comentario> <Mas_Comentarios>este es otro comentario</Mas_Comentarios> </Comentarios> <ID IDNumber="8">ID 8</ID> </COM>' SET @x.modify(' delete(/COM/ID/@IDNumber)') SELECT @x

Ejemplo 2

--borra el elemento Comentarios DECLARE @x xml set @x = '<COM> <ID IDNumber="9">ID 9</ID> <TipoVersion IDVersion="7">Interno</TipoVersion> <Comentarios> <Comentario IDUsuario="1">se debe apurar el cierre de la version</Comentario> <Mas_Comentarios>este es otro comentario</Mas_Comentarios> </Comentarios> <ID IDNumber="8">ID 8</ID> </COM>' SET @x.modify(' delete(/COM/Comentarios)') SELECT @x
Ejemplo 3

--ejemplo 3 --borra un texto de un nodo DECLARE @x xml set @x = '<COM> <ID IDNumber="9">ID 9</ID> <TipoVersion IDVersion="7">Interno</TipoVersion> <Comentarios> <Comentario IDUsuario="1">se debe apurar el cierre de la version</Comentario> <Mas_Comentarios>este es otro comentario</Mas_Comentarios> </Comentarios> <ID IDNumber="8">ID 8</ID> </COM>' SELECT @x SET @x.modify(' delete(/COM/ID/text())') SELECT @x

replace()
Actualiza el valor de un nodo en el documento

Ejemplo 1

--Actualiza texto del comentario DECLARE @x xml set @x = '<COM> <ID IDNumber="9">ID 9</ID> <TipoVersion IDVersion="7">Interno</TipoVersion> <Comentarios> <Comentario IDUsuario="1">se debe apurar el cierre de la version</Comentario> <Mas_Comentarios>este es otro comentario</Mas_Comentarios> </Comentarios> <ID IDNumber="8">ID 8</ID> </COM>' SET @x.modify(' replace value of(COM/Comentarios/Comentario/text())[1] with "Comentario Modificado" ') SELECT @x
Ejemplo 2

--Actualiza valor del atributo del ID DECLARE @x xml set @x = '<COM> <ID IDNumber="9">ID 9</ID> <TipoVersion IDVersion="7">Interno</TipoVersion> <Comentarios> <Comentario IDUsuario="1">se debe apurar el cierre de la version</Comentario> <Mas_Comentarios>este es otro comentario</Mas_Comentarios> </Comentarios> <ID IDNumber="8">ID 8</ID> </COM>' SET @x.modify(' replace value of (COM/ID/@IDNumber)[1] with "555"') SELECT @x

Apply
El operador APPLY permite invocar una funcin con valores de tabla para cada fila devuelta por una expresin de tabla externa de una consulta. La funcin con valores de tabla acta como la entrada derecha y la expresin de tabla externa como la entrada izquierda. La entrada derecha se evala para cada fila de la entrada izquierda y las filas producidas se combinan en la salida final. La lista de columnas producidas por el operador APPLY corresponde al conjunto de columnas de la entrada izquierda, seguido de la lista de columnas devueltas por la entrada derecha. Existen dos formas de APPLY: CROSS APPLY y OUTER APPLY. CROSS APPLY slo devuelve las filas de la tabla externa que producen un conjunto de resultados de la funcin con valores de tabla. OUTER APPLY devuelve tanto las filas que producen un conjunto de resultados como las que no, con valores NULL en la columna producida por la funcin con valores de tabla. Ejemplo Cross Apply

Generar select * de la tabla mtTRA_Trabajo para todos los trabajos con id igual a ID y que tengan Op igual a A en el xml de entrada (uso de "cross apply") DECLARE @z xml set @z = '<Proyecto> <Trabajo <Trabajo <Trabajo <Trabajo </Proyecto>'

Op="A" Op="A" Op="B" Op="B"

ID="1217" /> ID="1408" /> ID="2181" /> ID="10" />

SELECT Tbtr_IDTrabajo, tbtr_TipoTrabajo, tbtr_IDProyecto, tbtr_Producto, tbtr_IDVersion, tbtr_Producto, tbtr_Tema, tbtr_Nombre, tbtr_Objetivo, tbtr_Solicitado, tbtr_Cliente, tbtr_FechaCreacion, tbtr_IDTrabajoExt, tbtr_IDRecurso, tbtr_InicioEstimacion, tbtr_TerminoEstimacion, tbtr_UltExisteEstimacion, tbtr_UltDescripcion, tbtr_HorasEstimadas, tbtr_HorasInformadas, tbtr_HorasTerminar, tbtr_UltHEstimadas, tbtr_UltHInformadas, tbtr_UltHTerminar, tbtr_Estado, tbtr_NomRecurso, tbtr_Prioridad, tbtr_IDNamespace, tbtr_IDProdInterno FROM mtTRA_Trabajo CROSS APPLY @z.nodes('/Proyecto/Trabajo') AS P(IDTrabajo) WHERE tbtr_IDTrabajo = P.IDtrabajo.value('(@ID)[1]','int') AND P.IDtrabajo.value('(@Op)[1]','CHAR(1)') = 'A'
Resultado Parcial Se requera obtener todos los campos filtrando el ID que fuera igual a los dos valores que eran de A (1217 y 1408)

Modos RAW
El modo RAW transforma cada fila del conjunto de resultados de la consulta en un elemento XML que tiene el identificador genrico <row> o el nombre del elemento, que se proporciona de manera opcional. De manera predeterminada, cada valor de columna del conjunto de filas que no es NULL se asigna a un atributo del elemento <row>. Si se agrega la directiva ELEMENTS a la clusula FOR XML, cada valor de columna se asigna a un subelemento del elemento <row>. Opcionalmente, junto con la directiva ELEMENTS se puede especificar la opcin XSINIL para asignar los valores de columna NULL del conjunto de resultados a un elemento que tenga el atributo, xsi:nil="true". La opcin BINARY BASE64 se debe especificar en la clusula FOR XML para devolver los datos binarios en formato codificado en base 64. En el modo RAW, si se recuperan los datos binarios sin especificar la opcin BINARY BASE64, se produce un error. Se puede solicitar un esquema para el XML resultante. Si se especifica la opcin XMLDATA se devuelve un esquema XDR en lnea. Si se especifica la opcin XMLSCHEMA se devuelve un esquema XSD en lnea. El esquema aparece al principio de los datos. En el resultado, la referencia al espacio de nombres del esquema se repite en todos los elementos de nivel superior. Ejemplo En las consultas de los ejemplos siguientes se muestra cmo se utiliza el modo RAW de FOR XML

SELECT * FROM address FOR XML RAW


Resultado parcial
<row <row <row <row <row <row AddressID="1" AddressID="2" AddressID="3" AddressID="4" AddressID="5" AddressID="6" AddressType="Home" Address1="abc" Address2="xyz road" City="RJ" AgentID="1" /> AddressType="Office" Address1="temp" Address2="ppp road" City="RJ" AgentID="1" /> AddressType="Home" Address1="xxx" Address2="aaa road" City="NY" AgentID="2" /> AddressType="Office" Address1="ccc" Address2="oli Com" City="CL" AgentID="2" /> AddressType="Temp" Address1="eee" Address2="olkiu road" City="CL" AgentID="2" /> AddressType="Home" Address1="ttt" Address2="loik road" City="NY" AgentID="3" />

Se puede recuperar XML centrado en elementos si se especifica la directiva ELEMENTS.

SELECT * FROM address FOR XML RAW, elements


Resultado parcial

<row> <AddressID>1</AddressID> <AddressType>Home</AddressType> <Address1>abc</Address1> <Address2>xyz road</Address2> <City>RJ</City> <AgentID>1</AgentID> </row> <row> <AddressID>2</AddressID> <AddressType>Office</AddressType> <Address1>temp</Address1> <Address2>ppp road</Address2> <City>RJ</City> <AgentID>1</AgentID> </row>
Opcionalmente, se puede especificar la directiva TYPE para recuperar los resultados como de tipo xml. La directiva TYPE no cambia el contenido de los resultados. Slo afecta al tipo de datos de los resultados.

SELECT * FROM address FOR XML RAW, TYPE


Tambin es posible especificar el nodo que queremos que muestre

SELECT * FROM address FOR XML RAW('Direcciones'), TYPE


<Direcciones AddressID="1" AddressType="Home" Address1="abc" Address2="xyz road" City="RJ" AgentID="1" /> <Direcciones AddressID="2" AddressType="Office" Address1="temp" Address2="ppp road" City="RJ" AgentID="1" /> <Direcciones AddressID="3" AddressType="Home" Address1="xxx" Address2="aaa road" City="NY" AgentID="2" />

AUTO
El modo AUTO devuelve los resultados de una consulta como elementos XML anidados. Esto no ofrece un gran control sobre la forma del XML generado a partir del resultado de una consulta. Las consultas en modo AUTO son tiles si desea generar jerarquas sencillas. Sin embargo, Utilizar el modo EXPLICIT y Usar el modo PATH ofrecen un mayor control y una mayor flexibilidad a la hora de decidir la forma del XML procedente del resultado de una consulta. Cada tabla de la clusula FROM, de la que al menos se presenta una columna en la clusula SELECT, se representa como un elemento XML. Las columnas que se incluyen en la clusula SELECT se asignan a atributos o subelementos, si se especifica la opcin ELEMENTS en la clusula FOR XML. La jerarqua XML, anidamiento de los elementos, del XML resultante est basada en el orden de las tablas identificadas por las columnas especificadas en la clusula SELECT. Por tanto, el orden en que se especifican los nombres de columna en la clusula SELECT es importante. La primera, la tabla situada ms a la izquierda que se identifica, constituye el elemento superior del documento XML resultante. La segunda tabla situada ms a la izquierda, identificada por las columnas de la instruccin SELECT, constituye un subelemento del elemento superior, etc. Por ejemplo, ejecute esta consulta:

SELECT * FROM address FOR XML AUTO


ste es el resultado parcial:
<address <address <address <address <address <address AddressID="1" AddressID="2" AddressID="3" AddressID="4" AddressID="5" AddressID="6" AddressType="Home" Address1="abc" Address2="xyz road" City="RJ" AgentID="1" /> AddressType="Office" Address1="temp" Address2="ppp road" City="RJ" AgentID="1" /> AddressType="Home" Address1="xxx" Address2="aaa road" City="NY" AgentID="2" /> AddressType="Office" Address1="ccc" Address2="oli Com" City="CL" AgentID="2" /> AddressType="Temp" Address1="eee" Address2="olkiu road" City="CL" AgentID="2" /> AddressType="Home" Address1="ttt" Address2="loik road" City="NY" AgentID="3" />

Si se agrega la opcin ELEMENTS a la clusula FOR XML, se devuelve XML centrado en elementos.

SELECT * FROM address FOR XML AUTO, elements


ste es el resultado parcial:

<address> <AddressID>1</AddressID> <AddressType>Home</AddressType> <Address1>abc</Address1> <Address2>xyz road</Address2> <City>RJ</City> <AgentID>1</AgentID> </address> <address> <AddressID>2</AddressID> <AddressType>Office</AddressType> <Address1>temp</Address1> <Address2>ppp road</Address2> <City>RJ</City> <AgentID>1</AgentID> </address>..

PATH
El modo PATH facilita la combinacin de elementos y atributos. Tambin facilita la especificacin de anidacin adicional para representar propiedades complejas. Puede utilizar consultas de modo FOR XML EXPLICIT para generar XML a partir de un conjunto de filas, pero el modo PATH supone una alternativa ms sencilla a las consultas de modo EXPLICIT potencialmente complicadas. El modo PATH, junto con la posibilidad de escribir consultas FOR XML anidadas y la directiva TYPE para devolver instancias de tipo xml, permite escribir consultas de forma ms fcil. En el modo PATH, los nombres o alias de columna se tratan como expresiones XPath. Estas expresiones indican el modo en el que se asignan los valores a XML. Cada expresin XPath es una expresin relativa que proporciona el tipo de elemento, como el atributo, el elemento y el valor escalar, as como el nombre y la jerarqua del nodo que se generar en relacin con el elemento de fila.

Columnas sin nombre Las columnas sin nombre se insertarn entre lneas. Por ejemplo, las columnas calculadas o las consultas escalares anidadas que no especifiquen alias de columna generarn columnas sin nombre. Si la columna es de tipo xml, se insertar el contenido de esa instancia de tipo de datos. De lo contrario, el contenido de la columna se insertar como un nodo de texto.

SELECT 2+2 FOR XML path


Cree este XML. De forma predeterminada, por cada fila del conjunto de filas, se genera un elemento <row> en el XML resultante. Ocurre lo mismo que en el modo RAW.

<row>4</row>
Ejemplo

SELECT AddressID AS "@ID" FROM dbo.address WHERE AddressID = 1 for XML path('Nivel_1'), ROOT('Raiz_Direcciones')
Resultado

<Raiz_Direcciones> <Nivel_1 ID="1" /> </Raiz_Direcciones>

Ejemplo 2

SELECT AddressID FROM address WHERE AddressID = 1 for XML path('Nivel_1'), ROOT('Raiz_Direcciones')
Resultado

<Raiz_Direcciones> <Nivel_1> <AddressID>1</AddressID> </Nivel_1> </Raiz_Direcciones>

Ejemplo 3 En este ejemplo los valores con el smbolo @ representan el alias de cmo van a aparecer en el XML. La palabra ROOT indica que es la palabra Documento como ser llamada la raz del Xml y la palabra Direcciones representa el 2do nivel del Xml.

SELECT

AddressID AS "@ID", AddressType AS "@TipoDireccion", Address1 AS "@Direccion1", Address2 AS "@Direccion2", City AS "@Ciudad", AgentID AS "@IDAgente" FROM address FOR XML PATH('Direcciones'),ROOT('Documento')
Resultado Query

Ejemplo 4

SELECT AddressID AS "@ID",( SELECT

AddressType AS "@Type", Address1 AS "@Dire_1", Address1 AS "@Dire_2", City AS "@Ciudad", AgentID AS "@ID_Agente" FROM address FOR XML PATH('Nivel_Tipo'), type)

FROM dbo.address FOR XML PATH('Nivel_ID'), ROOT('Raiz_Direcciones')

Resultado parcial

Ejemplo con Inner Join

SELECT

AddressType AS "@Type", --<Hoja Type="Home"> AddressType, --<AddressType>Home</AddressType> Address1, --<Address1>abc</Address1> Address2, --<Address2>xyz road</Address2> Fname, --<Fname>Vimal</Fname> SSN --<SSN>123-23-4521</SSN> from address INNER JOIN dbo.agent on dbo.address.AgentID = dbo.agent.AgentID AND AddressID = 1 for xml path('Hoja'), root('Raiz')

Resultado

<Raiz> <Hoja Type="Home"> <AddressType>Home</AddressType> <Address1>abc</Address1> <Address2>xyz road</Address2> <Fname>Vimal</Fname> <SSN>123-23-4521</SSN> </Hoja> </Raiz>

EXPLICIT
El modo EXPLICIT transforma en un documento XML el conjunto de filas resultante de la ejecucin de la consulta. Para que el modo EXPLICIT pueda generar el documento XML, el conjunto de filas debe ajustarse a un determinado formato. Por ello, es necesario escribir la consulta SELECT para gemerar el conjunto de filas, la tabla universal, con un formato especfico que permita a la lgica del procesamiento generar el XML deseado. En primer lugar, la consulta debe crear las dos columnas de metadatos siguientes:

y y

La primera columna debe proporcionar el nmero de etiqueta, el tipo de entero, del elemento actual, y el nombre de la columna debe ser Tag. La consulta debe proporcionar un nmero de etiqueta nico para cada elemento que se vaya a construir a partir del conjunto de filas. La segunda columna debe proporcionar un nmero de etiqueta del elemento primario, y el nombre de la columna debe ser Parent. De este modo, las columnas Tag y Parent ofrecen informacin sobre la jerarqua.

Los valores de estas columnas de metadatos, junto con la informacin de los nombres de columna, se usan para generar el XML deseado. Tenga en cuenta que la consulta debe proporcionar los nombres de columna de una manera determinada. Observe tambin que un valor 0 NULL en la columna Parent indica que el elemento correspondiente no tiene uno primario. El elemento se agrega al XML como elemento de nivel superior. Para comprender cmo se procesa la tabla universal generada por una consulta para obtener el XML resultante, suponga que ha escrito una consulta que genera esta tabla universal:

Observe lo siguiente en esta tabla universal:

y y y

Las dos primeras columnas son Tag y Parent y son de metadatos. Estos valores determinan la jerarqua. Los nombres de columna se han especificado de una manera determinada, como se describe ms adelante en este tema. Al generar el XML a partir de esta tabla universal, se crea una particin vertical de los datos de la tabla en grupos de columnas. La agrupacin se determina en funcin del valor de Tag y los nombres de columna. Al crear XML, la lgica de procesamiento selecciona un grupo de columnas para cada fila y construye un elemento. En este ejemplo, se observa lo siguiente: y Para el valor 1 de la columna Tag en la primera fila, las columnas cuyos nombres incluyen el mismo nmero de etiqueta,Customer!1!cid y Customer!1!name, forman un grupo. Estas columnas se utilizan para procesar la fila, y se observa que la forma del elemento generado es <Customer id=... name=...>. El formato del nombre de columna se describe ms adelante en este tema. y Para las filas con valor 2 en la columna Tag, las columnas Order!2!id y Order!2!date forman un grupo que se usa despus para construir elementos, <Order id=... date=... />. y Para las filas con valor 3 en la columna Tag, las columnas OrderDetail!3!id!id y OrderDetail!3!pid!idref forman un grupo. Cada una de estas filas genera un elemento, <OrderDetail id=... pid=...>, a partir de estas columnas.

Tenga en cuenta que, al generar la jerarqua en XML, las filas se procesan por orden. La jerarqua XML se determina como se indica a continuacin:

La primera fila especifica el valor 1 en Tag y el valor NULL en Parent. Por lo tanto, el elemento correspondiente, <Customer>, se agrega al XML como elemento de nivel superior.

<Customer cid="C1" name="Janine"> y


La segunda fila identifica el valor 2 en Tag y el valor 1 en Parent. Por lo tanto, el elemento, <Order>, se agrega como elemento secundario de <Customer>.

<Customer cid="C1" name="Janine"> <Order id="O1" date="1/20/1996"> y


Las dos filas siguientes identifican el valor 3 en Tag y el valor 2 en Parent. Por lo tanto, los dos elementos <OrderDetail> se agregan como elementos secundarios de <Order>.

<Customer cid="C1" name="Janine"> <Order id="O1" date="1/20/1996"> <OrderDetail id="OD1" pid="P1"/> <OrderDetail id="OD2" pid="P2"/> y
La ltima fila identifica 2 como nmero de etiqueta en Tag y 1 como nmero de etiqueta en Parent. Por lo tanto, se agrega otro elemento secundario <Order> al elemento primario <Customer>.

<Customer cid="C1" name="Janine"> <Order id="O1" date="1/20/1996"> <OrderDetail id="OD1" pid="P1"/> <OrderDetail id="OD2" pid="P2"/> </Order> <Order id="O2" date="3/29/1997"> </Customer>
En resumen, los valores de las columnas de metadatos Tag y Parent, la informacin proporcionada en los nombres de columna y el orden correcto de las filas generan el XML deseado al utilizar el modo EXPLICIT.

Ordenacin de las filas en la tabla universal Al generar el XML, las filas de la tabla universal se procesan por orden. Por tanto, para recuperar las instancias secundarias correctas asociadas a su instancia primaria, las filas del conjunto de filas deben estar ordenadas de modo que a cada nodo principal le sigan directamente sus nodos secundarios.

Especificar nombres de columna en tabla Universal Al escribir consultas en modo EXPLICIT, los nombres de columna del conjunto de filas resultante se deben especificar con este formato. Ofrecen informacin de transformacin, incluidos nombres de elementos y atributos y otros datos, especificada mediante el uso de directivas. Sintaxis:

ElementName!TagNumber!AttributeName!Directive
Argumento: ElementName Es el identificador genrico resultante del elemento. Por ejemplo, si se especifica Customers como ElementName, se genera el elemento <Customers>. TagNumber Es un valor de etiqueta nico asignado a un elemento. Este valor, junto con las dos columnas de metadatos Tag y Parent, determina el anidamiento de los elementos en el XML resultante. AttributeName Proporciona el nombre del atributo que se va a crear en el identificador ElementName especificado. ste es el comportamiento si no se especifica Directive. Si se especifica Directive y es xml, cdata o element, este valor se utiliza para crear un elemento secundario de ElementName, y se le agrega el valor de la columna. Si se especifica Directive, AttributeName puede estar vaco. Por ejemplo, ElementName!TagNumber!!Directive. En este caso, el valor de la columna est incluido directamente en el ElementName. Directive Directive es opcional y se puede usar para proporcionar informacin adicional para generar el XML. Directive tiene dos objetivos. Uno de los objetivos es codificar valores como ID, IDREF e IDREFS. Puede especificar palabras clave ID, IDREF e IDREFS como valores de Directive. Estas directivas sobrescriben los tipos de atributo. De este modo, puede crear vnculos entre documentos. Tambin puede usar Directive para indicar la forma de asignar los datos de cadena a XML. Las palabras clave hide, element, elementxsinil, xml, xmltext y cdata se pueden usar como Directive. La directiva hide oculta el nodo. Es til cuando se recuperan valores slo para ordenarlos, sin incluirlos en el XML resultante.

La directiva element genera un elemento contenido en lugar de un atributo. Los datos contenidos se codifican como entidad. Por ejemplo, el carcter < pasa a ser &lt;. En el caso de valores de columna NULL, no se genera ningn elemento. Si desea que se genere un elemento para valores de columna NULL, puede especificar la directiva elementxsinil. De este modo, se generar un elemento con el atributo sxi:nil=TRUE. La directiva xml es la misma que la directiva element, excepto en que no se produce la codificacin de entidades. Observe que la directiva element se puede combinar con ID, IDREF o IDREFS, mientras que la directiva xml no se puede combinar con ninguna otra directiva, excepto hide. La directiva cdata Incluye los datos englobndolos en una seccin CDATA. El contenido no se codifica por entidad. El tipo de datos original debe ser de texto, como varchar, nvarchar, text o ntext. Esta directiva slo puede utilizarse con hide. Si se utiliza esta directiva, no debe especificarse AttributeName. La combinacin de directivas entre estos dos grupos es vlida en la mayora de los casos, pero no se permite la combinacin entre ellas mismas. Si no se especifican Directive ni AttributeName (por ejemplo, Customer!1), se implica una directiva element (comoCustomer!1!!element) y los datos de columna se incluyen en ElementName. Si se especifica la directiva xmltext, el contenido de la columna se incluye en una nica etiqueta que se integrar con el resto del documento. Esta directiva es til para recuperar los datos XML de desbordamiento no utilizados que OPENXML almacena en una columna. Para obtener ms informacin, vea Consultar XML con OPENXML. Si se especifica AttributeName, el nombre de etiqueta se sustituye por el nombre especificado. En caso contrario, el atributo se agrega a la lista actual de atributos de los elementos que los incluyen colocando el contenido al principio del contenido sin codificacin de entidades. La columna con esta directiva debe ser de tipo texto, como varchar, nvarchar, char, nchar, text o ntext. Esta directiva slo puede utilizarse con hide. Esta directiva es til para recuperar los datos de desbordamiento almacenados en una columna. Si el contexto no es un XML bien estructurado, el comportamiento no est definido. Ejemplo

SELECT

1 AS tag, NULL AS parent, NULL AS 'root!1!'-TAGNAME!TAGID FOR XML EXPLICIT

Resultado

<root />
Argumento Tagname: Representa el nombre que recibir la raz TagId: Representa el nivel en el que se est de XML

Ejemplo 2

SELECT

1 AS NULL NULL NULL

tag, AS parent,--indica que no tiene un padre que le anteceda. Esta AS 'address!1!',--TAGNAME!TAGID! AS 'addressID!2!ID'--TAGNAME!TAGID!ATTRIBUTENAME

es la raz

UNION ALL SELECT

2 AS tag,--indica que es el 2do tag 1 AS parent,--indica que su padre es el tag 1 NULL,--indica que el valor del padre aqui es nulo addressid--hace referencia al valor de la columna en este nivel FROM ADDRESS--desde la tabla FOR XML explicit
Resultado

<address> <addressID <addressID <addressID <addressID <addressID <addressID </address>

ID="1" ID="2" ID="3" ID="4" ID="5" ID="6"

/> /> /> /> /> />

Ejemplo 3

SELECT

tag, parent, [address!1!], [AddressID!2!ID], [AddressType!3!Type], [Address1!4!D1], [Address2!5!D2], [City!6!Ciudad], [AgentID!7!IDAgente]

FROM ( SELECT 1 AS tag, NULL AS parent, 0 AS sort, NULL AS 'address!1!', NULL AS 'AddressID!2!ID', NULL AS 'AddressType!3!Type', NULL AS 'Address1!4!D1', NULL AS 'Address2!5!D2', NULL AS 'City!6!Ciudad', NULL AS 'AgentID!7!IDAgente' UNION all SELECT 2 AS tag, 1 AS parent, addressId * 100 AS NULL, NULL, NULL, NULL FROM address UNION ALL SELECT 3 AS tag, 2 AS parent, addressId * 100 +1 addresstype, NULL, NULL, NULL, NULL FROM address UNION ALL SELECT 4 AS tag, 2 AS parent, addressId * 100 +2 address1, NULL, NULL, NULL FROM address UNION ALL SELECT 5 AS tag, 2 AS parent, addressId * 100 +3 NULL, address2, NULL, NULL FROM address UNION ALL SELECT 6 AS tag, 2 AS parent, addressId * 100 +4 NULL, NULL, city, NULL FROM address UNION ALL SELECT 7 AS tag, 2 AS parent, addressId * 100 +5 NULL, NULL, NULL, AgentID FROM address ) A ORDER BY sort FOR XML EXPLICIT

sort, NULL, addressid, NULL, AS sort, null, NULL, AS sort,NULL, NULL, NULL, AS sort, NULL, NULL, NULL, AS sort, NULL, NULL, NULL, AS sort, NULL, NULL, NULL,

Resultado

<address> <AddressID ID="1"> <AddressType Type="Home" /> <Address1 D1="abc" /> <Address2 D2="xyz road" /> <City Ciudad="RJ" /> <AgentID IDAgente="1" /> </AddressID> <AddressID ID="2"> <AddressType Type="Office" /> <Address1 D1="temp" /> <Address2 D2="ppp road" /> <City Ciudad="RJ" /> <AgentID IDAgente="1" /> </AddressID> <AddressID ID="3"> <AddressType Type="Home" /> <Address1 D1="xxx" /> <Address2 D2="aaa road" /> <City Ciudad="NY" /> <AgentID IDAgente="2" /> </AddressID> <AddressID ID="4"> <AddressType Type="Office" /> <Address1 D1="ccc" /> <Address2 D2="oli Com" /> <City Ciudad="CL" /> <AgentID IDAgente="2" /> </AddressID> <AddressID ID="5"> <AddressType Type="Temp" /> <Address1 D1="eee" /> <Address2 D2="olkiu road" /> <City Ciudad="CL" /> <AgentID IDAgente="2" /> </AddressID> <AddressID ID="6"> <AddressType Type="Home" /> <Address1 D1="ttt" /> <Address2 D2="loik road" /> <City Ciudad="NY" /> <AgentID IDAgente="3" /> </AddressID> </address>

Ejemplo con Element Element hace referencia al atributo que est, ver el Xml de salida

SELECT

tag, parent, [agents!1!], [Agent!2!AgentID], [Fname!3!Name!Element] 1 AS NULL 0 AS NULL NULL NULL tag, AS parent, sort, AS 'agents!1!', AS 'Agent!2!AgentID', AS 'Fname!3!Name!Element'

FROM ( SELECT

UNION ALL SELECT 2 AS tag, 1 AS parent, AgentID * 100 AS sort, NULL, AgentID, null FROM dbo.agent UNION ALL SELECT 3 AS tag, 2 AS parent, AgentID * 100 +1 AS sort, NULL, NULL, Fname FROM dbo.agent )A ORDER BY sort FOR XML explicit
Resultado

agents> <Agent AgentID="1"> <Fname> <Name>Vimal</Name> </Fname> </Agent> <Agent AgentID="2"> <Fname> <Name>Jacob</Name> </Fname> </Agent> <Agent AgentID="3"> <Fname> <Name>Tom</Name> </Fname> </Agent> </agents>

Ejemplo con Element 2

SELECT

tag, parent, [agents!1!], [Agent!2!AgentID], [Agent!2!Fname!Element], [Agent!3!FFN!Element] 1 AS NULL 0 AS NULL NULL NULL NULL tag, AS parent, sort, AS 'agents!1!', AS 'Agent!2!AgentID', AS 'Agent!2!Fname!Element', AS 'Agent!3!FFN!Element'

FROM ( SELECT

UNION ALL SELECT 2 AS tag, 1 AS parent, AgentID * 100 AS sort, NULL, AgentID, Fname, SSN FROM dbo.agent UNION ALL SELECT 3 AS tag, 2 AS parent, AgentID * 100 +1 AS sort, NULL, NULL, Fname, null FROM dbo.agent )A ORDER BY sort FOR XML explicit

Resultado

<agents> <Agent AgentID="1"> <Fname>Vimal</Fname> <Agent /> </Agent> <Agent AgentID="2"> <Fname>Jacob</Fname> <Agent /> </Agent> <Agent AgentID="3"> <Fname>Tom</Fname> <Agent /> </Agent> </agents>

Ejemplo inner Join

SELECT

1 AS tag, NULL AS parent, NULL AS 'RAIZ_AddressType!1!Type', NULL AS 'Hoja_Fname!2!Nombre' FROM dbo.agent INNER JOIN dbo.address ON dbo.agent.AgentID = dbo.address.AgentID WHERE dbo.address.AgentID = 1 UNION ALL SELECT 2 AS tag, 1 AS parent, null, Fname FROM dbo.agent INNER JOIN dbo.address on dbo.agent.AgentID = dbo.address.AgentID WHERE dbo.address.AgentID = 1 FOR XML explicit

Resultado

<RAIZ_AddressType /> <RAIZ_AddressType> <Hoja_Fname Nombre="Vimal" /> <Hoja_Fname Nombre="Vimal" /> </RAIZ_AddressType>

Errores de construccin Error: FOR XML EXPLICIT query contains the invalid column name '%1'. Use the TAGNAME!TAGID!ATTRIBUTENAME[!..] format where TAGID is a positive integer. Solucin: Quiere decir que en alguno de los select est mal el formato de null as address!1! y en el select anidado debe estar de la siguiente forma: [address!1!] Error: All queries combined using a UNION, INTERSECT or EXCEPT operator must have an equal number
of expressions in their target lists.

Solucin: Indica que entre alguno de los select que hay entre los union all no est la misma cantidad de elementos seleccionados

Das könnte Ihnen auch gefallen