Está en la página 1de 32

XML

Métodos Value()
Realiza una consulta XQuery en datos XML y devuelve un valor de tipo SQL. Este método devuelve un valor escalar. Normalmente, este método se utiliza para extraer un valor de una instancia XML almacenada en una columna, parámetro 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 método value() utiliza el operador CONVERT de Transact-SQL de manera implícita e intenta convertir el resultado de la expresión XQuery, la representación de cadena serializada, del tipo XSD al tipo SQL correspondiente especificado por la conversión Transact-SQL. Para obtener más información acerca de las reglas de conversión de tipos de CONVERT, vea CAST y CONVERT (Transact-SQL)

Sintaxis Value(XQuery, SQLType)

Argumentos XQUery: Es la expresión XQuery, un literal de cadena, que recupera los datos de la instancia XML. La expresión XQuery debe devolver un valor como máximo. 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 método coincide con el parámetro 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 expresión XQuery para una instancia de tipo de datos xml. El resultado es de tipo xml. El método devuelve una instancia XML sin tipo. Otra definición encontrada en internet podría 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 expresión 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, además 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

éstos se exponen en el conjunto de filas resultante. puede aplicar el método value() al conjunto de filas devuelto por nodes() y recuperar varios valores de la instancia XML original. Si la expresión de consulta construye nodos. Si se deja especificada la ruta mostrará solo o un año o el otro SELECT T./@A)[1]'. Table(column): Es el nombre de tabla y el nombre de columna del conjunto de filas resultante.nodes('/Festivos/Año/Mes') T(c) .c. En el caso de la instancia XML almacenada en una columna o variable.c. todo con su nombre correspondiente (uso de ". T.value('(. Puede recuperar varios valores del conjunto de filas.c.'CHAR(20)') AS Nombre FROM @y.Nodes() El método nodes() es muy útil si desea dividir una instancia de tipo de datos xml en datos relacionales.. éste es el nodo de documento. una expresión XQuery. Si la expresión de consulta da lugar estáticamente a una secuencia que contiene valores atómicos en lugar de nodos. Tenga en cuenta que el método value(). Permite identificar nodos que se asignarán a una fila nueva. el nodo de contexto de cada instancia de fila se establece en uno de los nodos identificados con la expresión de consulta.value('(@Nombre)[1]'. de manera que las consultas posteriores pueden navegar de forma relativa hasta estos nodos de contexto. cuando se aplica a la instancia XML.. Por ejemplo. Cada instancia de tipo de datos xml tiene un nodo de contexto proporcionado de manera implícita./@A): Hace posible que muestre año 2008 y 2009 donde corresponde para cada mes. el conjunto de filas estará vacío. Sintaxis Nodes(Xquery) as table(column) Argumentos XQuery: Es un literal de cadena.value('(@M)[1]'. Ejemplo -. se produce un error estático. devuelve sólo un valor. En estas copias lógicas.'int') AS Año. Si la expresión de consulta da lugar a una secuencia vacía.'int') AS mes. El resultado del método nodes() es un conjunto de datos que contiene copias lógicas de las instancias XML originales.Generar select normal con los valores contenidos en el xml.nodes()") DECLARE @y xml set @y = '<Festivos> <Año A="2008"> <Mes M="11" Nombre="Noviembre"/> <Mes M="12" Nombre="Diciembre"/> </Año> <Año A="2009"> <Mes M="1" Nombre="Enero"/> </Año> </Festivos>' (. El nodo de documento es el nodo implícito situado en la parte superior de cada instancia de tipo de datos xml. T.

devuelven un resultado no vacío. el método exist() devolverá 1. y y y El método XML exist() suele utilizarse en la cláusula WHERE de consultas SQL. 0. que los resultados posibles son: 1.exist('true()') . como se muestra en el ejemplo siguiente: Ejemplo 1 declare @x xml set @x='' select @x. porque las funciones true() y false() devuelven los valores booleanos True y False respectivamente. Si se especifican las funciones true() o false() dentro del método exist(). Por tanto. es NULL. un literal de cadena. de tal modo. Otra forma de sintaxis puede ser la siguiente que está siendo utilizado en el ejemplo 2: SELECT ProductName FROM Products WHERE XmlProduct. Sintaxis: exist(XQuery) XQuery : Es una expresión XQuery. si el dato XML que se está consultando.Resultado exist() Devuelve un bit como resultado de ejecutar una consulta XQuery sobre un dato XML. exist() devolverá 1 (True).exist( '/root[@Stock=sql:column("Stock")]') = 1 El método exist() devuelve 1 para la expresión XQuery que devuelve un resultado no vacío. si el resultado de la consulta XQuery es vacío. En otras palabras. si el resultado de la consulta XQuery NO es vacío. NULL.

exist('/Customer/Name[.Ejemplo 2 Conectándose 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.exist('/Person/Name[. 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('/Customer/Name = "John"') = 1 select customer_info from customers where customer_info.="John"]') Otros ejemplos de querys con sacados desde internet: select customer_info from customers where customer_info.exist('/Customer/Name/text()[.exist('/PRO/Producto[@Nombre = "MB"]') = 1 Ejemplo 3 Este ejemplo al ejecutarlo trae como resultado un boolean. 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 sería asi: SELECT tbpr_Productos from mtPRO_proyecto where tbpr_Productos. = "John"]') = 1 . = "John"]') = 1 --QUERY HECHA PARA CUANDO EL ATRIBUTO ESTA EN EL MEDIO DEL TAG select customer_info from customers where customer_info.

query('<Agent> <AgentID> "{sql:column("AgentID")}"</AgentID> <Fname> "{sql:column("Fname")}"</Fname> <SSN> "{sql:column("SSN")}"</SSN> </Agent>') FROM dbo.column() Se puede usar la función sql:column() cuando se utilicen métodos de tipo de datos XML para exponer un valor relacional dentro de XQuery. (³Fname´) y (³SSN´) porque hace referencia al nombre de la columna de la tabla.mbGLO_Config . <Fname> y <SSN> ponerle otros nombres y simplemente tendrán nombres diferentes cuando retorne el resultado de los datos.query se puede declarar de manera diferente la raíz <Agent> y sus hojas <AgentID>. Ejemplo 1 Dentro de el @x. Line 3 Invalid column name 'AgntID' DECLARE @x XML SET @x = '' SELECT @x. State 1. Level 16.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. Si por error es mal escrito retornará un error como el siguiente: Msg 207.agent Ejemplo 2 DECLARE @a XML SET @a = '' SELECT @a. Lo que NO PUEDE CAMBIAR es el valor que está dentro de el (³AgentID´).

En otras palabras. no se pueden escribir datos en las columnas que utilicen estas funciones. = sql:variable("@a")]') = 1 .exist('PRO/Producto [@Nombre = sql:variable("@b")]')=1 AND tbpr_productos.exist ('/DES/Datos/@Autor[.variable() Permite utilizar el valor de una variable de SQL en la expresión XQuery o XML Asimismo. este enlace es de sólo lectura.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. no se permite sql:variable("@x")="alguna expresión".mtLOG_Log 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. Por ejemplo. Ejemplo 1 DECLARE @b VARCHAR(10) DECLARE @c VARCHAR(10) SET @b = 'DI' SET @c = 'PDF' SELECT * FROM mtPRO_proyecto WHERE tbpr_productos.

Este método toma una instrucción XML DML para insertar.modify() Modifica el contenido de un documento XML. actualizar o eliminar nodos a partir de datos XML. Utilice este método para modificar el contenido de una columna o variable de tipo xml.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> . delete (XML DML) y replace value of (XML DML) insert() Inserta uno o más 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. Para mayor detalle es también utilizado con las funciones insert (XML DML).

modify(' insert text {"Texto insertado correctamente"} as first into (/COM)[1]') SELECT @x . SET @x.modify(' insert<ID IDNumber="8">ID 8</ID> as last into(/COM)[1]').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.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.

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. 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 .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.

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.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/ID/text())') SELECT @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 .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.

tbtr_Solicitado. tbtr_UltHInformadas. 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. tbtr_FechaCreacion. CROSS APPLY sólo devuelve las filas de la tabla externa que producen un conjunto de resultados de la función con valores de tabla.value('(@ID)[1]'. tbtr_IDNamespace.IDtrabajo. tbtr_Prioridad. tbtr_UltHTerminar. tbtr_HorasInformadas. 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. con valores NULL en la columna producida por la función con valores de tabla. tbtr_Tema. tbtr_UltExisteEstimacion.'int') AND P. tbtr_Producto. tbtr_IDProdInterno FROM mtTRA_Trabajo CROSS APPLY @z. tbtr_HorasTerminar. tbtr_UltDescripcion. tbtr_Objetivo. tbtr_IDRecurso.value('(@Op)[1]'. tbtr_Nombre. tbtr_Estado. tbtr_UltHEstimadas. tbtr_InicioEstimacion. tbtr_Producto. tbtr_NomRecurso. tbtr_IDVersion. OUTER APPLY devuelve tanto las filas que producen un conjunto de resultados como las que no. tbtr_TerminoEstimacion. tbtr_Cliente. La función con valores de tabla actúa como la entrada derecha y la expresión de tabla externa como la entrada izquierda.IDtrabajo. tbtr_IDTrabajoExt.nodes('/Proyecto/Trabajo') AS P(IDTrabajo) WHERE tbtr_IDTrabajo = P. tbtr_TipoTrabajo.'CHAR(1)') = 'A' Resultado Parcial Se requería obtener todos los campos filtrando el ID que fuera igual a los dos valores que eran de A (1217 y 1408) . Existen dos formas de APPLY: CROSS APPLY y OUTER APPLY. tbtr_IDProyecto. tbtr_HorasEstimadas. La entrada derecha se evalúa para cada fila de la entrada izquierda y las filas producidas se combinan en la salida final.Apply El operador APPLY permite invocar una función con valores de tabla para cada fila devuelta por una expresión de tabla externa de una consulta.

si se recuperan los datos binarios sin especificar la opción BINARY BASE64. la referencia al espacio de nombres del esquema se repite en todos los elementos de nivel superior. xsi:nil="true". Si se agrega la directiva ELEMENTS a la cláusula FOR XML. La opción BINARY BASE64 se debe especificar en la cláusula FOR XML para devolver los datos binarios en formato codificado en base 64. Si se especifica la opción XMLSCHEMA se devuelve un esquema XSD en línea. que se proporciona de manera opcional. se produce un error. En el resultado.Modos RAW El modo RAW transforma cada fila del conjunto de resultados de la consulta en un elemento XML que tiene el identificador genérico <row> o el nombre del elemento. De manera predeterminada. cada valor de columna se asigna a un subelemento del elemento <row>. Se puede solicitar un esquema para el XML resultante. En el modo RAW. junto con la directiva ELEMENTS se puede especificar la opción XSINIL para asignar los valores de columna NULL del conjunto de resultados a un elemento que tenga el atributo. cada valor de columna del conjunto de filas que no es NULL se asigna a un atributo del elemento <row>. Opcionalmente. Si se especifica la opción XMLDATA se devuelve un esquema XDR en línea. Ejemplo En las consultas de los ejemplos siguientes se muestra cómo 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" /> . El esquema aparece al principio de los datos.

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. TYPE También es posible especificar el nodo que queremos que muestre SELECT * FROM address FOR XML RAW('Direcciones').Se puede recuperar XML centrado en elementos si se especifica la directiva ELEMENTS. SELECT * FROM address FOR XML RAW. SELECT * FROM address FOR XML RAW. La directiva TYPE no cambia el contenido de los resultados. Sólo afecta al tipo de datos de los resultados. 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" /> . se puede especificar la directiva TYPE para recuperar los resultados como de tipo xml.

identificada por las columnas de la instrucción SELECT. se devuelve XML centrado en elementos. Sin embargo. . se representa como un elemento XML. Cada tabla de la cláusula FROM. 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>«««««««««««.AUTO El modo AUTO devuelve los resultados de una consulta como elementos XML anidados. Por ejemplo. etc. La jerarquía XML. La segunda tabla situada más a la izquierda. La primera. 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. Las consultas en modo AUTO son útiles si desea generar jerarquías sencillas. de la que al menos se presenta una columna en la cláusula SELECT. el orden en que se especifican los nombres de columna en la cláusula SELECT es importante. anidamiento de los elementos. Las columnas que se incluyen en la cláusula SELECT se asignan a atributos o subelementos.. si se especifica la opción ELEMENTS en la cláusula FOR XML. constituye el elemento superior del documento XML resultante. Por tanto. del XML resultante está basada en el orden de las tablas identificadas por las columnas especificadas en la cláusula SELECT. la tabla situada más a la izquierda que se identifica. 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 opción ELEMENTS a la cláusula FOR XML. SELECT * FROM address FOR XML AUTO. Esto no ofrece un gran control sobre la forma del XML generado a partir del resultado de una consulta. constituye un subelemento del elemento superior.

junto con la posibilidad de escribir consultas FOR XML anidadas y la directiva TYPE para devolver instancias de tipo xml. De lo contrario. se genera un elemento <row> en el XML resultante. Estas expresiones indican el modo en el que se asignan los valores a XML. Ocurre lo mismo que en el modo RAW. Puede utilizar consultas de modo FOR XML EXPLICIT para generar XML a partir de un conjunto de filas. el contenido de la columna se insertará como un nodo de texto.PATH El modo PATH facilita la combinación de elementos y atributos. como el atributo. los nombres o alias de columna se tratan como expresiones XPath. SELECT 2+2 FOR XML path Cree este XML. pero el modo PATH supone una alternativa más sencilla a las consultas de modo EXPLICIT potencialmente complicadas. De forma predeterminada. por cada fila del conjunto de filas. permite escribir consultas de forma más fácil. En el modo PATH. Si la columna es de tipo xml. El modo PATH. el elemento y el valor escalar. así como el nombre y la jerarquía del nodo que se generará en relación con el elemento de fila. También facilita la especificación de anidación adicional para representar propiedades complejas. ROOT('Raiz_Direcciones') Resultado <Raiz_Direcciones> <Nivel_1 ID="1" /> </Raiz_Direcciones> . Columnas sin nombre Las columnas sin nombre se insertarán entre líneas. se insertará el contenido de esa instancia de tipo de datos. Por ejemplo. <row>4</row> Ejemplo SELECT AddressID AS "@ID" FROM dbo.address WHERE AddressID = 1 for XML path('Nivel_1'). las columnas calculadas o las consultas escalares anidadas que no especifiquen alias de columna generarán columnas sin nombre. Cada expresión XPath es una expresión relativa que proporciona el tipo de elemento.

City AS "@Ciudad". La palabra ROOT indica que es la palabra µDocumento¶ como será llamada la raíz del Xml y la palabra µDirecciones¶ representa el 2do nivel del Xml. Address2 AS "@Direccion2".Ejemplo 2 SELECT AddressID FROM address WHERE AddressID = 1 for XML path('Nivel_1').ROOT('Documento') Resultado Query . ROOT('Raiz_Direcciones') Resultado <Raiz_Direcciones> <Nivel_1> <AddressID>1</AddressID> </Nivel_1> </Raiz_Direcciones> Ejemplo 3 En este ejemplo los valores con el símbolo @ representan el alias de cómo van a aparecer en el XML. AgentID AS "@IDAgente" FROM address FOR XML PATH('Direcciones'). AddressType AS "@TipoDireccion". SELECT AddressID AS "@ID". Address1 AS "@Direccion1".

Address1 AS "@Dire_2". AgentID AS "@ID_Agente" FROM address FOR XML PATH('Nivel_Tipo'). type) FROM dbo.Ejemplo 4 SELECT AddressID AS "@ID".( SELECT AddressType AS "@Type".address FOR XML PATH('Nivel_ID'). City AS "@Ciudad". ROOT('Raiz_Direcciones') Resultado parcial . Address1 AS "@Dire_1".

--<Address2>xyz road</Address2> Fname. --<Fname>Vimal</Fname> SSN --<SSN>123-23-4521</SSN> from address INNER JOIN dbo.address.Ejemplo con Inner Join SELECT AddressType AS "@Type". 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> .agent.agent on dbo.AgentID = dbo.AgentID AND AddressID = 1 for xml path('Hoja'). --<AddressType>Home</AddressType> Address1. --<Hoja Type="Home"> AddressType. --<Address1>abc</Address1> Address2.

. <Order id=. el conjunto de filas debe ajustarse a un determinado formato.>..EXPLICIT El modo EXPLICIT transforma en un documento XML el conjunto de filas resultante de la ejecución de la consulta.. y Para las filas con valor 2 en la columna Tag.. del elemento actual.. es necesario escribir la consulta SELECT para gemerar el conjunto de filas. se usan para generar el XML deseado. se observa lo siguiente: y Para el valor 1 de la columna Tag en la primera fila. Estas columnas se utilizan para procesar la fila. las columnas cuyos nombres incluyen el mismo número de etiqueta. Para que el modo EXPLICIT pueda generar el documento XML. el tipo de entero.. la lógica de procesamiento selecciona un grupo de columnas para cada fila y construye un elemento. la tabla universal. La agrupación se determina en función del valor de Tag y los nombres de columna. Los nombres de columna se han especificado de una manera determinada... name=. las columnas OrderDetail!3!id!id y OrderDetail!3!pid!idref forman un grupo.. las columnas Order!2!id y Order!2!date forman un grupo que se usa después para construir elementos. como se describe más adelante en este tema. Al generar el XML a partir de esta tabla universal. En este ejemplo. La consulta debe proporcionar un número de etiqueta único para cada elemento que se vaya a construir a partir del conjunto de filas. En primer lugar. Observe también que un valor 0 ó NULL en la columna Parent indica que el elemento correspondiente no tiene uno primario. El formato del nombre de columna se describe más adelante en este tema. Tenga en cuenta que la consulta debe proporcionar los nombres de columna de una manera determinada. se crea una partición vertical de los datos de la tabla en grupos de columnas. . Por ello. las columnas Tag y Parent ofrecen información sobre la jerarquía. y el nombre de la columna debe ser Tag. junto con la información de los nombres de columna. <OrderDetail id=.Customer!1!cid y Customer!1!name. Cada una de estas filas genera un elemento. Para comprender cómo se procesa la tabla universal generada por una consulta para obtener el XML resultante. con un formato específico que permita a la lógica del procesamiento generar el XML deseado. pid=. Los valores de estas columnas de metadatos. la consulta debe crear las dos columnas de metadatos siguientes: y y La primera columna debe proporcionar el número de etiqueta. Estos valores determinan la jerarquía. De este modo.. a partir de estas columnas. La segunda columna debe proporcionar un número de etiqueta del elemento primario.>. El elemento se agrega al XML como elemento de nivel superior. y Para las filas con valor 3 en la columna Tag. />. date=. Al crear XML.. 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. y se observa que la forma del elemento generado es <Customer id=. forman un grupo.. y el nombre de la columna debe ser Parent.

al generar la jerarquía en XML. el elemento correspondiente. Por lo tanto. <Customer cid="C1" name="Janine"> y La segunda fila identifica el valor 2 en Tag y el valor 1 en Parent. <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. se agrega otro elemento secundario <Order> al elemento primario <Customer>. se agrega al XML como elemento de nivel superior. se agrega como elemento secundario de <Customer>. Por lo tanto. <Customer>. Por lo tanto. La jerarquía XML se determina como se indica a continuación: y La primera fila especifica el valor 1 en Tag y el valor NULL en Parent. el elemento. <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 número de etiqueta en Tag y 1 como número de etiqueta en Parent.y Tenga en cuenta que. <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. <Order>. . Por lo tanto. los dos elementos <OrderDetail> se agregan como elementos secundarios de <Order>. los valores de las columnas de metadatos Tag y Parent. la información proporcionada en los nombres de columna y el orden correcto de las filas generan el XML deseado al utilizar el modo EXPLICIT. las filas se procesan por orden.

Este valor. las filas de la tabla universal se procesan por orden. Estas directivas sobrescriben los tipos de atributo. AttributeName puede estar vacío. Si se especifica Directive y es xml. De este modo. Directive Directive es opcional y se puede usar para proporcionar información adicional para generar el XML. . Ofrecen información de transformación. Es útil cuando se recuperan valores sólo para ordenarlos. el valor de la columna está incluido directamente en el ElementName. se genera el elemento <Customers>. En este caso. Por tanto. Si se especifica Directive. y se le agrega el valor de la columna. elementxsinil. junto con las dos columnas de metadatos Tag y Parent. Directive tiene dos objetivos. sin incluirlos en el XML resultante. Éste es el comportamiento si no se especifica Directive. Especificar nombres de columna en tabla Universal Al escribir consultas en modo EXPLICIT. Uno de los objetivos es codificar valores como ID. Por ejemplo. Sintaxis: ElementName!TagNumber!AttributeName!Directive Argumento: ElementName Es el identificador genérico resultante del elemento. para recuperar las instancias secundarias correctas asociadas a su instancia primaria. La directiva hide oculta el nodo. incluidos nombres de elementos y atributos y otros datos. si se especifica Customers como ElementName. AttributeName Proporciona el nombre del atributo que se va a crear en el identificador ElementName especificado. determina el anidamiento de los elementos en el XML resultante. También puede usar Directive para indicar la forma de asignar los datos de cadena a XML. ElementName!TagNumber!!Directive. puede crear vínculos entre documentos. xmltext y cdata se pueden usar como Directive. Puede especificar palabras clave ID. element. Por ejemplo. cdata o element. las filas del conjunto de filas deben estar ordenadas de modo que a cada nodo principal le sigan directamente sus nodos secundarios. xml. este valor se utiliza para crear un elemento secundario de ElementName. IDREF e IDREFS. Las palabras clave hide.Ordenación de las filas en la tabla universal Al generar el XML. los nombres de columna del conjunto de filas resultante se deben especificar con este formato. especificada mediante el uso de directivas. TagNumber Es un valor de etiqueta único asignado a un elemento. IDREF e IDREFS como valores de Directive.

NULL AS parent. char. En caso contrario. como varchar. El tipo de datos original debe ser de texto. Esta directiva es útil para recuperar los datos XML de desbordamiento no utilizados que OPENXML almacena en una columna. La directiva xml es la misma que la directiva element. Esta directiva sólo puede utilizarse con hide. Si se especifica AttributeName. el comportamiento no está definido. Esta directiva es útil para recuperar los datos de desbordamiento almacenados en una columna. no debe especificarse AttributeName.La directiva element genera un elemento contenido en lugar de un atributo. como varchar. Customer!1). En el caso de valores de columna NULL. La combinación de directivas entre estos dos grupos es válida en la mayoría de los casos. Para obtener más información. Esta directiva sólo puede utilizarse con hide. El contenido no se codifica por entidad.. Los datos contenidos se codifican como entidad. Por ejemplo. text o ntext. el atributo se agrega a la lista actual de atributos de los elementos que los incluyen colocando el contenido al principio del contenido sin codificación de entidades. excepto en que no se produce la codificación de entidades. De este modo. Si no se especifican Directive ni AttributeName (por ejemplo. se generará un elemento con el atributo sxi:nil=TRUE. Si el contexto no es un XML bien estructurado. se implica una directiva element (comoCustomer!1!!element) y los datos de columna se incluyen en ElementName. mientras que la directiva xml no se puede combinar con ninguna otra directiva. el carácter < pasa a ser &lt. IDREF o IDREFS. La columna con esta directiva debe ser de tipo texto. vea Consultar XML con OPENXML. Si se utiliza esta directiva. el contenido de la columna se incluye en una única etiqueta que se integrará con el resto del documento. pero no se permite la combinación entre ellas mismas. NULL AS 'root!1!'²-TAGNAME!TAGID FOR XML EXPLICIT Resultado <root /> Argumento Tagname: Representa el nombre que recibirá la raíz TagId: Representa el nivel en el que se está de XML . nvarchar. Observe que la directiva element se puede combinar con ID. nchar. La directiva cdata Incluye los datos englobándolos en una sección CDATA. Si desea que se genere un elemento para valores de columna NULL. nvarchar. no se genera ningún elemento. excepto hide. Ejemplo SELECT 1 AS tag. text o ntext. puede especificar la directiva elementxsinil. Si se especifica la directiva xmltext. el nombre de etiqueta se sustituye por el nombre especificado.

AS parent.--indica que no tiene un padre que le anteceda. Esta AS 'address!1!'.--indica que es el 2do tag 1 AS parent.--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" /> /> /> /> /> /> .--TAGNAME!TAGID! AS 'addressID!2!ID'--TAGNAME!TAGID!ATTRIBUTENAME es la raíz UNION ALL SELECT 2 AS tag.Ejemplo 2 SELECT 1 AS NULL NULL NULL tag.--indica que su padre es el tag 1 NULL.

addressId * 100 +2 address1. NULL. NULL. [City!6!Ciudad]. 2 AS parent. NULL. addressId * 100 AS NULL. NULL FROM address UNION ALL SELECT 3 AS tag. . 0 AS sort. NULL AS 'address!1!'. NULL FROM address UNION ALL SELECT 7 AS tag. address2. NULL. 2 AS parent. [AddressType!3!Type]. AS sort. addressId * 100 +5 NULL. NULL.NULL. [AgentID!7!IDAgente] FROM ( SELECT 1 AS tag. city. 2 AS parent. NULL. 2 AS parent. NULL AS 'AgentID!7!IDAgente' UNION all SELECT 2 AS tag. NULL AS parent. AS sort. [AddressID!2!ID]. NULL FROM address UNION ALL SELECT 5 AS tag. NULL. NULL. NULL. NULL. NULL. 2 AS parent. NULL. AgentID FROM address ) A ORDER BY sort FOR XML EXPLICIT sort. parent. addressId * 100 +1 addresstype. NULL. AS sort. NULL. 1 AS parent. NULL AS 'Address1!4!D1'. [Address1!4!D1]. NULL. null. [address!1!]. NULL. NULL. NULL. NULL. AS sort. NULL. NULL AS 'AddressID!2!ID'. NULL. addressId * 100 +3 NULL. addressid. NULL FROM address UNION ALL SELECT 6 AS tag. addressId * 100 +4 NULL. NULL AS 'AddressType!3!Type'. AS sort. NULL AS 'City!6!Ciudad'. NULL FROM address UNION ALL SELECT 4 AS tag. NULL. NULL. NULL AS 'Address2!5!D2'. NULL.Ejemplo 3 SELECT tag. [Address2!5!D2]. 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> .

NULL. AS 'agents!1!'. AgentID * 100 AS sort. null 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> . Fname FROM dbo. [Agent!2!AgentID]. sort. NULL. [Fname!3!Name!Element] 1 AS NULL 0 AS NULL NULL NULL tag. [agents!1!]. AgentID * 100 +1 AS sort.Ejemplo con Element Element hace referencia al atributo que está. 2 AS parent. AS parent. NULL. AgentID. AS 'Fname!3!Name!Element' FROM ( SELECT UNION ALL SELECT 2 AS tag. AS 'Agent!2!AgentID'. ver el Xml de salida SELECT tag. 1 AS parent.agent UNION ALL SELECT 3 AS tag. parent.

[Agent!2!Fname!Element].Ejemplo con Element 2 SELECT tag.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> . 1 AS parent. NULL. AgentID * 100 AS sort. AS 'Agent!2!Fname!Element'. [agents!1!]. NULL. [Agent!2!AgentID]. AS 'Agent!2!AgentID'. AgentID. sort. Fname. parent. null FROM dbo. SSN FROM dbo. AS 'agents!1!'. AgentID * 100 +1 AS sort. [Agent!3!FFN!Element] 1 AS NULL 0 AS NULL NULL NULL NULL tag. Fname. AS parent.agent UNION ALL SELECT 3 AS tag. NULL. 2 AS parent. AS 'Agent!3!FFN!Element' FROM ( SELECT UNION ALL SELECT 2 AS tag.

Fname FROM dbo.address.agent INNER JOIN dbo. NULL AS 'Hoja_Fname!2!Nombre' FROM dbo.AgentID = 1 FOR XML explicit Resultado <RAIZ_AddressType /> <RAIZ_AddressType> <Hoja_Fname Nombre="Vimal" /> <Hoja_Fname Nombre="Vimal" /> </RAIZ_AddressType> .address.AgentID WHERE dbo.agent. 1 AS parent. NULL AS 'RAIZ_AddressType!1!Type'.AgentID WHERE dbo.agent.address on dbo.AgentID = dbo.Ejemplo inner Join SELECT 1 AS tag.address. NULL AS parent.AgentID = dbo.address.agent INNER JOIN dbo.AgentID = 1 UNION ALL SELECT 2 AS tag. null.address ON dbo.

. Use the TAGNAME!TAGID!ATTRIBUTENAME[!. INTERSECT or EXCEPT operator must have an equal number of expressions in their target lists.Errores de construcción Error: FOR XML EXPLICIT query contains the invalid column name '%1'. Solución: 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.] format where TAGID is a positive integer. Solución: Indica que entre alguno de los select que hay entre los union all no está la misma cantidad de elementos seleccionados .