You are on page 1of 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

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

En otras palabras. si el resultado de la consulta XQuery es vacío.exist('true()') . si el dato XML que se está consultando. es NULL. si el resultado de la consulta XQuery NO es vacío. 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(). el método exist() devolverá 1. Otra forma de sintaxis puede ser la siguiente que está siendo utilizado en el ejemplo 2: SELECT ProductName FROM Products WHERE XmlProduct. exist() devolverá 1 (True). de tal modo.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. un literal de cadena. devuelven un resultado no vacío. que los resultados posibles son: 1. Por tanto.Resultado exist() Devuelve un bit como resultado de ejecutar una consulta XQuery sobre un dato XML. 0. y y y El método XML exist() suele utilizarse en la cláusula WHERE de consultas SQL. Sintaxis: exist(XQuery) XQuery : Es una expresión XQuery. NULL. como se muestra en el ejemplo siguiente: Ejemplo 1 declare @x xml set @x='' select @x.

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

Line 3 Invalid column name 'AgntID' DECLARE @x XML SET @x = '' SELECT @x. Level 16.query('<Agent> <AgentID> "{sql:column("AgentID")}"</AgentID> <Fname> "{sql:column("Fname")}"</Fname> <SSN> "{sql:column("SSN")}"</SSN> </Agent>') FROM dbo. Si por error es mal escrito retornará un error como el siguiente: Msg 207. Lo que NO PUEDE CAMBIAR es el valor que está dentro de el (³AgentID´).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> 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. State 1.mbGLO_Config .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. (³Fname´) y (³SSN´) porque hace referencia al nombre de la columna de la tabla.agent Ejemplo 2 DECLARE @a XML SET @a = '' SELECT @a.

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

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> .modify() Modifica el contenido de un documento XML. Utilice este método para modificar el contenido de una columna o variable de tipo xml. Este método toma una instrucción XML DML para insertar. 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). actualizar o eliminar nodos a partir de datos XML.

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]').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 . 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. 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. 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(' 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.

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

IDtrabajo. tbtr_UltDescripcion. OUTER APPLY devuelve tanto las filas que producen un conjunto de resultados como las que no. tbtr_IDNamespace. tbtr_IDProdInterno FROM mtTRA_Trabajo CROSS APPLY @z.'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) .nodes('/Proyecto/Trabajo') AS P(IDTrabajo) WHERE tbtr_IDTrabajo = P. tbtr_NomRecurso. tbtr_HorasTerminar. tbtr_InicioEstimacion. tbtr_Solicitado. 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_TipoTrabajo. tbtr_Estado. tbtr_Objetivo. tbtr_IDProyecto.'int') AND P. tbtr_UltHInformadas. con valores NULL en la columna producida por la función con valores de tabla. tbtr_Prioridad.value('(@Op)[1]'. tbtr_Producto. tbtr_HorasInformadas. tbtr_IDRecurso. tbtr_HorasEstimadas.IDtrabajo. La entrada derecha se evalúa para cada fila de la entrada izquierda y las filas producidas se combinan en la salida final. tbtr_TerminoEstimacion. Existen dos formas de APPLY: CROSS APPLY y OUTER APPLY. tbtr_UltExisteEstimacion. tbtr_Nombre. tbtr_FechaCreacion. tbtr_UltHEstimadas. La lista de columnas producidas por el operador APPLY corresponde al conjunto de columnas de la entrada izquierda. 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. La función con valores de tabla actúa como la entrada derecha y la expresión de tabla externa como la entrada izquierda. tbtr_IDTrabajoExt. tbtr_Cliente. tbtr_IDVersion. seguido de la lista de columnas devueltas por la entrada derecha. tbtr_Producto. tbtr_UltHTerminar.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. tbtr_Tema.

la referencia al espacio de nombres del esquema se repite en todos los elementos de nivel superior. xsi:nil="true". El esquema aparece al principio de los datos. Si se especifica la opción XMLSCHEMA se devuelve un esquema XSD en línea. Si se especifica la opción XMLDATA se devuelve un esquema XDR en línea. Si se agrega la directiva ELEMENTS a la cláusula FOR XML. 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" /> . Opcionalmente. En el resultado. si se recuperan los datos binarios sin especificar la opción BINARY BASE64. cada valor de columna del conjunto de filas que no es NULL se asigna a un atributo del elemento <row>. Se puede solicitar un esquema para el XML resultante. se produce un error. 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. En el modo RAW. De manera predeterminada. cada valor de columna se asigna a un subelemento del elemento <row>. que se proporciona de manera opcional. 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.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.

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

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

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

AddressType AS "@TipoDireccion". Address1 AS "@Direccion1". SELECT AddressID AS "@ID". City AS "@Ciudad".Ejemplo 2 SELECT AddressID FROM address WHERE AddressID = 1 for XML path('Nivel_1'). 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. AgentID AS "@IDAgente" FROM address FOR XML PATH('Direcciones'). 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. Address2 AS "@Direccion2".ROOT('Documento') Resultado Query .

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

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

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

se agrega como elemento secundario de <Customer>. <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. 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. <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. los dos elementos <OrderDetail> se agregan como elementos secundarios de <Order>. el elemento correspondiente. al generar la jerarquía en XML. el elemento. los valores de las columnas de metadatos Tag y Parent. Por lo tanto. <Customer cid="C1" name="Janine"> y La segunda fila identifica el valor 2 en Tag y el valor 1 en Parent.y Tenga en cuenta que. . Por lo tanto. Por lo tanto. se agrega al XML como elemento de nivel superior. se agrega otro elemento secundario <Order> al elemento primario <Customer>. 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. <Customer>. Por lo tanto. las filas se procesan por orden. <Order>. <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.

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

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

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

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

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

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

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

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.. Solución: Indica que entre alguno de los select que hay entre los union all no está la misma cantidad de elementos seleccionados .] format where TAGID is a positive integer. Use the TAGNAME!TAGID!ATTRIBUTENAME[!.