sql con xml

28
ESCUELA POLITÉCNICA NACIONAL FACULTAD DE INGENIERÍA DE SISTEMAS BASE DE DATOS Integrantes Edison Quisiguiña David Montúfar Pablo Guachamín Roberto Lema Fabián Vásquez INTRODUCCION A XML Lenguajes de Marcas En los años 60, IBM intentó resolver sus problemas asociados al tratamiento de documentos en diferentes plataformas a través de GML (Generalized markup Language). El principal problema era que cada aplicación utilizaba sus propias marcas para describir los diferentes elementos. Las marcas son códigos que indican a un programa cómo debe tratar su contenido y así, si se desea que un texto aparezca con un formato determinado, dicho texto debe ir delimitado por la correspondiente marca que indique como debe ser mostrado en pantalla o impreso. Y lo mismo ocurre con todas las demás características de cualquier texto. Ejemplos pueden tenerlos en mente los usuarios de WordPerfect. Conociendo este sistema y conociendo a la perfección el sistema de marcas de cada aplicación sería posible pasar información de un sistema a otro sin necesidad de perder el formato indicado. La forma que IBM creó para solventar esto se basaba en tratar las marcas como texto accesible desde cualquier sistema, texto plano, código ASCII. Y la norma se denominó GML (General Modeling Language). Más tarde GML pasó a manos de ISO y se convirtio en SGML ( ISO 8879), Standart Generalized Markup Language. Esta norma es la que se aplica desde entonces a todos los lenguajes de marcas, cuyos ejemplos más conocidos son el HTML y el RTF. Los lenguajes de marcas no son equivalentes a los lenguajes de programación aunque se definan igualmente como "lenguajes". Son sistemas complejos de descripción de información, normalmente documentos, que si se ajustan a SGML, se pueden controlar desde cualquier editor ASCII. Las marcas más utilizadas suelen describirse por textos descriptivos encerrados entre signos de "menor" (<) y "mayor" (>), siendo lo más usual que existan una marca de principio y otra de final. Se puede decir que existen tres utilizaciones básicas de los lenguajes de marcas: los que sirven principalmente para describir su contenido, los que sirven más que nada para definir su formato y los que realizan las dos funciones indistintamente. Las aplicaciones de bases de datos son buenas referencias del primer sistema, los programas de tratamiento de textos son ejemplos típicos del segundo tipo, y aunque no lo parezca, el HTML es la muestra más conocida del tercer modelo. ¿Qué es XML? XML, es el estandar de Extensible Markup Language. XML no es más que un conjunto de reglas para definir etiquetas semánticas que nos organizan un documento en diferentes partes. XML es un metalenguaje que define la sintaxis utilizada para definir otros lenguajes de etiquetas estructurados. En primer lugar para entenderlo bien hay que olvidarse un poco, sólo un poco de HTML. En teoría HTML es un subconjunto de XML especializado en presentación de documentos para la Web, mientras que XML es un subconjunto de SGML especializado en la gestión de información para la Web. En la práctica XML contiene a HTML aunque no en su totalidad. La definición de HTML contenido totalmente dentro de XML y por lo tanto que cumple a rajatabla la especificación SGML es XHTML (Extensible, Hypertext Markup Language).

Upload: ataraxioj

Post on 14-Jun-2015

2.480 views

Category:

Documents


3 download

DESCRIPTION

Proyecto Final SQL Avanzado

TRANSCRIPT

Page 1: SQL con XML

ESCUELA POLITÉCNICA NACIONAL

FACULTAD DE INGENIERÍA DE SISTEMAS

BASE DE DATOS

Integrantes

Edison Quisiguiña

David Montúfar

Pablo Guachamín

Roberto Lema

Fabián Vásquez

INTRODUCCION A XML

Lenguajes de Marcas

En los años 60, IBM intentó resolver sus problemas asociados al tratamiento de documentos en diferentes

plataformas a través de GML (Generalized markup Language).

El principal problema era que cada aplicación utilizaba sus propias marcas para describir los diferentes

elementos. Las marcas son códigos que indican a un programa cómo debe tratar su contenido y así, si se desea

que un texto aparezca con un formato determinado, dicho texto debe ir delimitado por la correspondiente

marca que indique como debe ser mostrado en pantalla o impreso. Y lo mismo ocurre con todas las demás

características de cualquier texto. Ejemplos pueden tenerlos en mente los usuarios de WordPerfect.

Conociendo este sistema y conociendo a la perfección el sistema de marcas de cada aplicación sería posible

pasar información de un sistema a otro sin necesidad de perder el formato indicado. La forma que IBM creó

para solventar esto se basaba en tratar las marcas como texto accesible desde cualquier sistema, texto plano,

código ASCII. Y la norma se denominó GML (General Modeling Language).

Más tarde GML pasó a manos de ISO y se convirtio en SGML ( ISO 8879), Standart Generalized Markup

Language. Esta norma es la que se aplica desde entonces a todos los lenguajes de marcas, cuyos ejemplos más

conocidos son el HTML y el RTF.

Los lenguajes de marcas no son equivalentes a los lenguajes de programación aunque se definan igualmente

como "lenguajes". Son sistemas complejos de descripción de información, normalmente documentos, que si se

ajustan a SGML, se pueden controlar desde cualquier editor ASCII. Las marcas más utilizadas suelen describirse

por textos descriptivos encerrados entre signos de "menor" (<) y "mayor" (>), siendo lo más usual que existan

una marca de principio y otra de final.

Se puede decir que existen tres utilizaciones básicas de los lenguajes de marcas: los que sirven principalmente

para describir su contenido, los que sirven más que nada para definir su formato y los que realizan las dos

funciones indistintamente. Las aplicaciones de bases de datos son buenas referencias del primer sistema, los

programas de tratamiento de textos son ejemplos típicos del segundo tipo, y aunque no lo parezca, el HTML es

la muestra más conocida del tercer modelo.

¿Qué es XML?

XML, es el estandar de Extensible Markup Language. XML no es más que un conjunto de reglas para definir

etiquetas semánticas que nos organizan un documento en diferentes partes. XML es un metalenguaje que

define la sintaxis utilizada para definir otros lenguajes de etiquetas estructurados.

En primer lugar para entenderlo bien hay que olvidarse un poco, sólo un poco de HTML. En teoría HTML es un

subconjunto de XML especializado en presentación de documentos para la Web, mientras que XML es un

subconjunto de SGML especializado en la gestión de información para la Web. En la práctica XML contiene a

HTML aunque no en su totalidad. La definición de HTML contenido totalmente dentro de XML y por lo tanto

que cumple a rajatabla la especificación SGML es XHTML (Extensible, Hypertext Markup Language).

Page 2: SQL con XML

Desde su creación, XML ha despertado encontradas pasiones, y como para cualquier tema en Internet, hay

gente que desde el principio se deja iluminar por sus expectativas, mientras otras muchas lo han ignorado.

CREAR VARIABLES Y COLUMNAS DEL TIPO DE DATOS XML

El tipo de datos xml es un tipo de datos integrado de SQL Server y es similar a otros tipos integrados como int

y varchar. Al igual que ocurre con otros tipos integrados, se puede utilizar el tipo de datos xml como un tipo de

columna al crear una tabla como un tipo de variable, un tipo de parámetro, un tipo de valor devuelto por una

función o en CAST y CONVERT.

Crear columnas y variables

Para crear una columna de tipo XML como parte de una tabla utilizaremos la instrucción CREATE TABLE.

CREATE TABLE T1(Col1 int primary key, Col2 xml)

La declaración de una variable de tipo XML se realiza mediante la instrucción DECLARE, especificando

una colección de esquemas XML.

DECLARE @x xml (Sales.StoreSurveySchemaCollection)

Para pasar un parámetro de tipo xml a un procedimiento almacenado, se emplea la instrucción CREATE

PROCEDURE.

CREATE PROCEDURE SampleProc(@XmlDoc xml) AS ...

Asignar valores predeterminados

En una tabla, puede asignar una instancia XML predeterminada a una columna de tipo xml. Puede proporcionar

el XML predeterminado de una de estas dos maneras: con una constante XML o con una conversión explícita al

tipo xml.

Para proporcionar el XML predeterminado como una constante XML se lo debe realizar como se

muestra a continuación. Observe que la cadena se convierte implícitamente al tipo xml.

CREATE TABLE T (XmlColumn xml default N'<element1/><element2/>')

Para proporcionar el XML predeterminado mediante una operación de conversión (CAST) explícita a xml.

Por ejemplo:

CREATE TABLE T (XmlColumn xml

default CAST(N'<element1/><element2/>' AS xml))

SQL Server también admite restricciones NULL y NOT NULL en columnas de tipo xml. Por ejemplo: CREATE TABLE T (XmlColumn xml NOT NULL)

Page 3: SQL con XML

Especificar restricciones

Al crear columnas de tipo xml, puede definir restricciones de nivel de columna o de nivel de tabla. Las

restricciones se emplean en estas situaciones:

Las reglas de su empresa no se pueden expresar en esquemas XML. Por ejemplo, la dirección de entrega

de una floristería debe estar a menos de 75 kilómetros de su ubicación. Esto se puede escribir como una

restricción en la columna XML. La restricción puede afectar a métodos de tipo de datos xml.

La restricción afecta a otras columnas XML o no XML de la tabla. Un ejemplo puede ser obligar a que el

Id. de un cliente (/Customer/@CustId) existente en una instancia XML coincida con el valor de una

columna relacional CustomerID.

Puede especificar restricciones para columnas de tipo de datos xml con o sin tipo. Sin embargo, no puede usar

los métodos de tipo de datos XML al especificar restricciones. También debe tener en cuenta que el tipo de

datos xml no admite las restricciones de columna y de tabla siguientes:

PRIMARY KEY / FOREIGN KEY

UNIQUE

COLLATE

XML proporciona su propia codificación. Las intercalaciones sólo se aplican a los tipos de cadena. El tipo

de datos xml no es un tipo de cadena. No obstante, tiene una representación de cadena y permite la

conversión a tipos de datos de cadena y desde tipos de datos de cadena.

RULE

Una alternativa al uso de restricciones consiste en crear una función de contenedor definida por el usuario para

ajustar el método de tipo de datos xml y especificar una función definida por el usuario en la restricción CHECK,

como se muestra a continuación.

En el siguiente ejemplo, la restricción de Col2 especifica que cada instancia XML almacenada en esta columna

debe tener un elemento <ProductDescription> con un atributo ProductID. Esta restricción se exige mediante la

siguiente función definida por el usuario:

CREATE FUNCTION my_udf(@var xml) returns bit

AS BEGIN

RETURN @var.exist('/ProductDescription/@ProductID')

END

GO

Observe que el método exist() del tipo de datos xml devuelve 1 si el elemento <ProductDescription> de la

instancia contiene el atributo ProductID. De lo contrario, devuelve 0.

En este momento, puede crear una tabla con una restricción de columna del modo siguiente:

CREATE TABLE T (

Col1 int primary key,

Col2 xml check(dbo.my_udf(Col2)=1))

GO

La inserción siguiente se realiza correctamente:

INSERT INTO T values(1,'<ProductDescription ProductID="1" />')

Page 4: SQL con XML

La inserción siguiente no se realiza correctamente a causa de la restricción:

INSERT INTO T values(1,'<Product />')

COMPARACIÓN DE XML CON TIPO Y XML SIN TIPO

Se pueden crear variables, parámetros y columnas del tipo de datos xml. Opcionalmente, se puede asociar una

colección de esquemas XML a una variable, a un parámetro o a una columna de tipo xml. En este caso, se

dice que la instancia del tipo de datos xml es una instancia con tipo. En los demás casos, se dice que la instancia

XML es una instancia sin tipo.

XML correcto y tipo de datos XML

El tipo de datos xml implementa el tipo de datos xml del estándar ISO. Por lo tanto, puede almacenar

documentos XML versión 1.0 correctos, así como los denominados fragmentos de contenido XML con nodos de

texto y un número arbitrario de elementos de nivel superior en una columna XML sin tipo. El sistema comprueba

que todos los datos tienen un formato correcto, no requiere que la columna esté enlazada a esquemas XML y

rechaza los datos que no tienen un formato correcto en sentido amplio. Esto también se cumple para

parámetros y variables XML sin tipo.

Esquemas XML

Un esquema XML proporciona lo siguiente:

Restricciones de validación. Siempre que se asigna o modifica una instancia XML con tipo, SQL Server

valida la instancia.

Información sobre el tipo de datos. Los esquemas proporcionan información sobre los tipos de

atributos y elementos de la instancia de tipo de datos xml. La información de tipo proporciona una

semántica operacional más precisa para los valores contenidos en la instancia que es posible con xml

sin tipo. Por ejemplo, se pueden realizar operaciones aritméticas con decimales en un valor decimal,

pero no en un valor de cadena. Por este motivo, el almacenamiento de XML con tipo puede ser mucho

más compacto que el de XML sin tipo.

Elegir XML con tipo o sin tipo

El tipo de datos xml sin tipo se emplea en las siguientes situaciones:

No tiene un esquema para los datos XML.

Tiene esquemas pero no desea que el servidor valide los datos. Esto a veces ocurre cuando una

aplicación realiza la validación en el cliente antes de almacenar los datos en el servidor, almacena

temporalmente datos XML que no son válidos según el esquema, o usa componentes del esquema que

no son compatibles con el servidor.

El tipo de datos xml con tipo se emplea en las siguientes situaciones:

Tiene esquemas para los datos XML y desea que el servidor valide estos datos según los esquemas XML.

Desea aprovechar las optimizaciones del almacenamiento y de las consultas en función de la

información del tipo.

Desea aprovechar mejor la información del tipo durante la compilación de las consultas.

Columnas, parámetros y variables XML con tipo pueden almacenar documentos o contenido XML. No obstante,

hay que especificar con un indicador si se va a almacenar un documento o contenido en el momento de la

declaración. Además, hay que proporcionar la colección de esquemas XML. Especifique DOCUMENT si cada

instancia XML tiene exactamente un elemento de nivel superior. En caso contrario, use CONTENT. El compilador

de consultas usa el indicador DOCUMENT en comprobaciones de tipo durante la compilación de consultas para

inferir elementos singleton de nivel superior.

Page 5: SQL con XML

Crear XML con tipo

Para poder crear variables, parámetros o columnas xml con tipo, primero es necesario registrar la colección de

esquemas XML mediante CREATE XML SCHEMA COLLECTION (Transact-SQL). Después, se puede asociar la

colección de esquemas XML a variables, parámetros o columnas del tipo de datos xml.

En los ejemplos siguientes se usa una convención de nomenclatura de dos partes para especificar el nombre de

la colección de esquemas XML. La primera parte corresponde al nombre de esquema de AdventureWorks y la

segunda corresponde al nombre de la colección de esquemas XML.

Ejemplo: Asociar una colección de esquemas con una variable de tipo XML

En el ejemplo siguiente se crea una variable de tipo xml y se le asocia una colección de esquemas. La colección

de esquemas especificada en el ejemplo ya se ha importado a la base de datos AdventureWorks. DECLARE @x xml (Production.ProductDescriptionSchemaCollection)

Ejemplo: Especificar un esquema para una columna de tipo XML

En el ejemplo siguiente se crea una tabla con una columna de tipo xml y se especifica un esquema para la

columna: CREATE TABLE T1(

Col1 int,

Col2 xml (Production.ProductDescriptionSchemaCollection))

Ejemplo: Pasar un parámetro de tipo XML a un procedimiento almacenado

En el ejemplo siguiente se pasa un parámetro de tipo xml a un procedimiento almacenado y se especifica un

esquema para la variable: CREATE PROCEDURE SampleProc

@ProdDescription xml (Production.ProductDescriptionSchemaCollection)

AS

Tenga en cuenta lo siguiente sobre la colección de esquemas XML:

Una colección de esquemas XML sólo está disponible en la base de datos en la que se ha registrado

mediante CREATE XML SCHEMA COLLECTION.

Si se realiza la conversión de una cadena a un tipo de datos xml con tipo, el análisis también realiza la

validación y la conversión de tipos, de acuerdo con los espacios de nombres de los esquemas XML de la

colección especificada.

Es posible convertir un tipo de datos xml con tipo en un tipo de datos xml sin tipo, y viceversa.

Para obtener más información sobre otras maneras de generar XML en SQL Server, vea Generar instancias XML.

Una vez generado el XML, se puede asignar a una variable del tipo de datos xml o se puede almacenar en

columnas de tipo xml para su posterior procesamiento.

En la jerarquía de tipos de datos, el tipo de datos xml aparece por debajo de sql_variant y los tipos definidos

por el usuario, pero por encima de los tipos integrados.

Ejemplo: Especificar aspectos para restringir una columna XML con tipo

En las columnas xml con tipo se puede restringir la columna para permitir que sólo se almacene en ella un único

elemento de nivel superior para cada instancia. Para ello, se especifica el aspecto opcional DOCUMENT cuando

se crea una tabla, como se muestra en el ejemplo siguiente: CREATE TABLE T(Col1 xml

(DOCUMENT Production.ProductDescriptionSchemaCollection))

GO

DROP TABLE T

GO

De manera predeterminada, las instancias se almacenan en la columna xml con tipo como contenido XML y no

como documentos XML. Esto permite lo siguiente:

Cero o varios elementos de nivel superior

Nodos de texto en elementos de nivel superior

Page 6: SQL con XML

Este comportamiento también se puede especificar explícitamente, agregando el aspecto CONTENT, tal y como

se muestra en el ejemplo siguiente: CREATE TABLE T(Col1 xml(CONTENT Production.ProductDescriptionSchemaCollection))

GO -- Default

Tenga en cuenta que puede especificar los aspectos de DOCUMENT/CONTENT opcionales en cualquier lugar

donde defina un tipo el xml (XML con tipo). Por ejemplo, cuando se crea una variable xml con tipo, se puede

agregar el aspecto DOCUMENT/CONTENT, como se muestra a continuación: declare @x xml (DOCUMENT Production.ProductDescriptionSchemaCollection)

Definición de tipo de documento (DTD)

Las columnas de tipo de datos xml, las variables y los parámetros pueden obtener tipos utilizando un esquema

XML, pero no mediante DTD. Sin embargo, se puede usar DTD en línea para XML con o sin tipo, para suministrar

valores predeterminados y reemplazar referencias a entidades por su forma expandida.

Puede convertir las DTD en documentos de esquemas XML mediante herramientas de otros fabricantes y cargar

los esquemas XML en la base de datos.

Actualizar XML con tipo de SQL Server 2005 a SQL Server 2008

SQL Server 2008 ha realizado varias extensiones a la compatibilidad con esquemas XML, incluyendo la

compatibilidad para la validación lax, el control mejorado de xs:date, xs:time y datos de instancia xs:dateTime,

y compatibilidad agregada para tipos de lista y tipos de unión. En la mayoría de los casos, los cambios no

afectan a la experiencia de actualización. Sin embargo si usa una colección de esquemas XML en SQL Server

2005 que permitia valores del tipo xs:date, xs:time o xs:dateTime (o cualquier subtipo), los pasos de

actualización siguientes se producen al asociar la base de datos de SQL Server 2005 a SQL Server 2008:

1. Para cada columna XML, que se escribe con una Colección de esquemas XML que contiene elementos o

atributos escritos como xs:anyType, xs:anySimpleType, xs:date o cualquiera de sus subtipos, xs:time

o cualquier subtipo, o xs:dateTime o cualquiera de sus subtipos ,o son tipos de unión o de lista que

contienen cualquiera de estos tipos, se produce lo siguiente:

a) Se deshabilitarán todos los índices XML de la columna.

b) Todos los valores de SQL Server 2005 continuarán representándose en la zona horaria Z porque

se han normalizado a dicha zona horaria.

c) Cualquier valor xs:date o xs:dateTime que sea menor que el 1 de enero del año 1 llevará a un

error en tiempo de ejecución cuando el índice se regenere o se ejecute una XQuery o

instrucciones XML-DML frente al tipo de datos XML que contiene dicho valor.

2. Cualquier año negativo en los aspectos o valores predeterminados de xs:date o xs:dateTime de una

colección de esquemas XML se actualizará automáticamente al valor más pequeño permitido por el tipo

base xs:date o xs:dateTime (por ejemplos, 0001-01-01T00:00:00.0000000Z para xs:dateTime).

Observe que todavía puede usar una instrucción SELECT de SQL para recuperar todo el tipo de datos XML, aun

cuando contiene años negativos. Se recomienda que reemplace los años negativos por un año dentro del

intervalo recientemente admitido o cambie el tipo del elemento o atributo a xs:string.

MÉTODOS DE TIPO DE DATOS XML

Puede utilizar los métodos del tipo de datos xml para realizar una consulta en una instancia XML almacenada en

una variable o columna de tipo xml. En los temas de esta sección se describe cómo utilizar los métodos del tipo

de datos xml.

En esta sección

Page 7: SQL con XML

Tema Descripción

query() (método de tipo de

datos xml)

Describe cómo utilizar el método query() para realizar una consulta en

una instancia XML.

value() (método del tipo de

datos xml)

Describe cómo utilizar el método value() para recuperar un valor de tipo

SQL de una instancia XML.

exist() (método del tipo de

datos xml)

Describe cómo utilizar el método exist() para determinar si una consulta

devuelve un resultado no vacío.

Modify() (método del tipo de

datos xml)

Describe cómo utilizar el método modify() para especificar instrucciones

XML Data Modification Language (XML DML) para realizar las

actualizaciones.

nodes() (método del tipo de

datos XML)

Describe cómo utilizar el método nodes() para dividir XML en varias filas,

lo que propaga partes de documentos XML en conjuntos de filas.

Enlazar datos relacionales

dentro de datos XML

Describe cómo enlazar datos no XML dentro de XML.

Directrices para utilizar los

métodos del tipo de datos xml

Describe instrucciones para utilizar los métodos de tipo de datos xml.

Estos métodos se llaman mediante la sintaxis de llamada de métodos de tipo definido por el usuario. Por

ejemplo:

SELECT XmlCol.query(' ... ')

FROM Table

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.

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:

Esta sección muestra ejemplos de cómo utilizar el método query() de tipo de datos xml.

A. Usar el método query() con una variable de tipo xml

El ejemplo siguiente declara una variable @myDoc de tipo xml y le asigna una instancia XML. A continuación,

se utiliza el método query() para especificar una expresión XQuery para el documento.

La consulta recupera el elemento secundario <Features> del elemento <ProductDescription>: declare @myDoc xml

set @myDoc = '<Root>

Page 8: SQL con XML

<ProductDescription ProductID="1" ProductName="Road Bike">

<Features>

<Warranty>1 year parts and labor</Warranty>

<Maintenance>3 year parts and labor extended maintenance is

available</Maintenance>

</Features>

</ProductDescription>

</Root>'

SELECT @myDoc.query('/Root/ProductDescription/Features')

El resultado es el siguiente: <Features>

<Warranty>1 year parts and labor</Warranty>

<Maintenance>3 year parts and labor extended maintenance is

available</Maintenance>

</Features>

B. Usar el método query() con una columna de tipo XML

En el ejemplo siguiente, el método query() se utiliza para especificar una expresión XQuery para la columna

CatalogDescription de tipo xml en la base de datos AdventureWorks: SELECT CatalogDescription.query('

declare namespace PD="http://schemas.microsoft.com/sqlserver/2004/07/adventure-

works/ProductModelDescription";

<Product ProductModelID="{ /PD:ProductDescription[1]/@ProductModelID }" />

') as Result

FROM Production.ProductModel

where CatalogDescription.exist('

declare namespace PD="http://schemas.microsoft.com/sqlserver/2004/07/adventure-

works/ProductModelDescription";

declare namespace wm="http://schemas.microsoft.com/sqlserver/2004/07/adventure-

works/ProductModelWarrAndMain";

/PD:ProductDescription/PD:Features/wm:Warranty ') = 1

Observe lo siguiente en la consulta anterior:

La columna CatalogDescription es una columna xml con tipo. Esto quiere decir que tiene asociada una

colección de esquemas. En el prólogo de XQuery, la palabra clave namespace se utiliza para definir el

prefijo que se utilizará posteriormente en el cuerpo de la consulta.

El método query() crea XML, un elemento <Product> que tiene el atributo ProductModelID, en el que

el valor de atributo ProductModelID se recupera a partir de la base de datos. Para obtener más

información acerca de la creación de XML, vea Construcción de XML (XQuery).

El método exist() del tipo de datos xml en la cláusula WHERE se utiliza para buscar sólo filas que

contengan el elemento <Warranty> en el XML. La palabra clave namespace se utiliza nuevamente para

definir dos prefijos de espacios de nombres.

Éste es el resultado parcial: <Product ProductModelID="19"/>

<Product ProductModelID="23"/>

...

value() (método del tipo de datos xml)

Realiza una consulta XQuery en datos XML y devuelve un valor de tipo SQL. Este método devuelve un valor

escalar.

Page 9: SQL con XML

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.

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.

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

Por motivos de rendimiento, en lugar de utilizar el método value() en un predicado para la comparación con un

valor relacional, utilice exist() con sql:column(). Esto se muestra en el ejemplo D a continuación.

Ejemplos

A. Utilizar el método value() con una variable de tipo xml

En el ejemplo siguiente, una instancia XML está almacenada en una variable de tipo xml. El método value()

recupera el valor del atributo ProductID en el XML. Después, el valor se asigna a una variable int. DECLARE @myDoc xml

DECLARE @ProdID int

SET @myDoc = '<Root>

<ProductDescription ProductID="1" ProductName="Road Bike">

<Features>

<Warranty>1 year parts and labor</Warranty>

<Maintenance>3 year parts and labor extended maintenance is

available</Maintenance>

</Features>

</ProductDescription>

</Root>'

SET @ProdID = @myDoc.value('(/Root/ProductDescription/@ProductID)[1]', 'int' )

SELECT @ProdID

Como resultado se devuelve el valor 1.

Aunque hay un solo atributo ProductID en la instancia XML, las reglas de los tipos estáticos requieren que se

especifique explícitamente que la expresión de ruta de acceso devuelva un singleton. Por tanto, se especifica [1]

al final de la expresión de ruta de acceso. Para obtener más información acerca de los tipos estáticos, vea

XQuery y el establecimiento de tipos estáticos.

B. Utilizar el método value() para recuperar un valor de una columna de tipo xml

La siguiente consulta se especifica sobre una columna de tipo xml (CatalogDescription) de la base de datos

AdventureWorks. La consulta recupera los valores del atributo ProductModelID de cada instancia XML

almacenada en la columna. SELECT CatalogDescription.value('

Page 10: SQL con XML

declare namespace

PD="http://schemas.microsoft.com/sqlserver/2004/07/adventure-

works/ProductModelDescription";

(/PD:ProductDescription/@ProductModelID)[1]', 'int') AS Result

FROM Production.ProductModel

WHERE CatalogDescription IS NOT NULL

ORDER BY Result desc

Observe lo siguiente en la consulta anterior:

Se utiliza la palabra clave namespace para definir un prefijo de espacio de nombres.

Según los requisitos de los tipos estáticos, se agrega [1] al final de la expresión de ruta de acceso del

método value() para indicar explícitamente que la expresión de ruta de acceso devuelva un singleton.

Éste es el resultado parcial: -----------

35

34

...

C. Utilizar los métodos value() y exist() para recuperar valores de una columna de tipo xml

En el siguiente ejemplo se muestra el uso del método value() y el método exist() del tipo de datos xml. El

método value() se utiliza para recuperar los valores del atributo ProductModelID del XML. El método exist() de la

cláusula WHERE se utiliza para filtrar las filas de la tabla.

La consulta recupera los identificadores de modelo de producto de las instancias XML que incluyen información

de garantía (el elemento <Warranty>) entre sus características. La condición de la cláusula WHERE utiliza el

método exist() para recuperar únicamente las filas que cumplan esta condición. SELECT CatalogDescription.value('

declare namespace

PD="http://schemas.microsoft.com/sqlserver/2004/07/adventure-

works/ProductModelDescription";

(/PD:ProductDescription/@ProductModelID)[1] ', 'int') as Result

FROM Production.ProductModel

WHERE CatalogDescription.exist('

declare namespace

PD="http://schemas.microsoft.com/sqlserver/2004/07/adventure-

works/ProductModelDescription";

declare namespace

wm="http://schemas.microsoft.com/sqlserver/2004/07/adventure-

works/ProductModelWarrAndMain";

/PD:ProductDescription/PD:Features/wm:Warranty ') = 1

Observe lo siguiente en la consulta anterior:

La columna CatalogDescription es una columna XML con tipo. Esto significa que tiene asociada una

colección de esquemas. En el prólogo de las consultas XQuery, se utiliza la declaración del espacio de

nombres para definir el prefijo que se utilizará posteriormente en el cuerpo de la consulta.

Si el método exist() devuelve 1 (True), significa que la instancia XML incluye el elemento secundario

<Warranty> entre sus características.

Después, el método value() de la cláusula SELECT recupera los valores del atributo ProductModelID

como enteros.

Éste es el resultado parcial: Result

-----------

19

23

Page 11: SQL con XML

...

D. Utilizar el método exist() en lugar del método value()

Por motivos de rendimiento, en lugar de utilizar el método value() de un predicado para compararlo con un

valor relacional, utilice exist() con sql:column(). Por ejemplo: CREATE TABLE T (c1 int, c2 varchar(10), c3 xml)

GO

SELECT c1, c2, c3

FROM T

WHERE c3.value( '/root[1]/@a', 'integer') = c1

GO

Esto se puede escribir de la forma siguiente: SELECT c1, c2, c3

FROM T

WHERE c3.exist( '/root[@a=sql:column("c1")]') = 1

GO

exist() (método del tipo de datos xml)

Devuelve un bit que representa una de las condiciones siguientes:

1, que representa True, si la expresión XQuery de una consulta devuelve un resultado no vacío, es decir,

si devuelve al menos un nodo XML.

0, que representa False, si devuelve un resultado vacío.

NULL si la instancia con datos del tipo xml con la que se ejecuta la consulta incluye valores NULL.

El método exist() devuelve 1 para la expresión XQuery que devuelve un resultado no vacío. Si se especifican las

funciones true() o false() dentro del método exist(), el método exist() devolverá 1, porque las funciones true()

y false() devuelven los valores booleanos True y False respectivamente. En otras palabras, devuelven un

resultado no vacío. Por tanto, exist() devolverá 1 (True), como se muestra en el ejemplo siguiente:

declare @x xml set @x=''

select @x.exist('true()')

Sintaxis exist (XQuery)

Argumentos

XQuery

Es una expresión XQuery, un literal de cadena.

Ejemplos

En los ejemplos siguientes se muestra cómo especificar el método exist().

Ejemplo: especificar el método exist() con una variable de tipo xml

En el ejemplo siguiente, @x es una variable de tipo xml (xml sin tipo) y @f es una variable de tipo entero que

almacena el valor devuelto por el método exist(). El método exist() devuelve True (1) si el valor de fecha

almacenado en la instancia XML es 2002-01-01. declare @x xml

declare @f bit

set @x = '<root Somedate = "2002-01-01Z"/>'

set @f = @x.exist('/root[(@Somedate cast as xs:date?) eq xs:date("2002-01-01Z")]')

select @f

Page 12: SQL con XML

Al comparar las fechas del método exist(), tenga en cuenta lo siguiente:

El código cast as xs:date? se utiliza para convertir el valor al tipo xs:date con fines comparativos.

El valor del atributo @Somedate no tiene tipo. Al comparar este valor, se convierte implícitamente al

tipo de la derecha de la comparación, el tipo xs:date.

En lugar de cast as xs:date(), puede utilizar la función constructora xs:date(). Para obtener más

información, vea Funciones de constructor (XQuery).

El ejemplo siguiente es similar al anterior, con la diferencia de que tiene un elemento <Somedate>. DECLARE @x xml

DECLARE @f bit

SET @x = '<Somedate>2002-01-01Z</Somedate>'

SET @f = @x.exist('/Somedate[(text()[1] cast as xs:date ?) = xs:date("2002-01-

01Z") ]')

SELECT @f

Observe lo siguiente en la consulta anterior:

El método text() devuelve un nodo de texto que incluye el valor sin tipo 2002-01-01. El tipo XQuery es

xdt:untypedAtomic. Debe convertir explícitamente este valor con tipo de x a xsd:date, puesto que en

este caso no se admite la conversión implícita.

Ejemplo: especificar el método exist() con una variable xml con tipo

En el ejemplo siguiente se muestra el uso del método exist() con una variable del tipo xml. Se trata de una

variable XML con tipo, pues especifica el nombre de la colección del espacio de nombres del esquema,

ManuInstructionsSchemaCollection.

En este ejemplo, en primer lugar se asigna a esta variable un documento con instrucciones de fabricación y, a

continuación, se utiliza el método exist() para comprobar si el documento incluye un elemento <Location>

cuyo valor del atributo LocationID es 50.

El método exist() especificado con la variable @x devuelve 1 (True) si el documento con instrucciones de

fabricación incluye un elemento <Location> con LocationID=50. De lo contrario, el método devolverá 0 (False). DECLARE @x xml (Production.ManuInstructionsSchemaCollection)

SELECT @x=Instructions

FROM Production.ProductModel

WHERE ProductModelID=67

--SELECT @x

DECLARE @f int

SET @f = @x.exist(' declare namespace

AWMI="http://schemas.microsoft.com/sqlserver/2004/07/adventure-

works/ProductModelManuInstructions";

/AWMI:root/AWMI:Location[@LocationID=50]

')

SELECT @f

Ejemplo: especificar el método exist() con una columna de tipo xml

La consulta siguiente recupera los Id. de modelo de producto cuyas descripciones de catálogo no incluyen las

especificaciones, elemento <Specifications>: SELECT ProductModelID, CatalogDescription.query('

declare namespace pd="http://schemas.microsoft.com/sqlserver/2004/07/adventure-

works/ProductModelDescription";

<Product

ProductModelID= "{ sql:column("ProductModelID") }"

/>

') AS Result

FROM Production.ProductModel

WHERE CatalogDescription.exist('

Page 13: SQL con XML

declare namespace

pd="http://schemas.microsoft.com/sqlserver/2004/07/adventure-

works/ProductModelDescription";

/pd:ProductDescription[not(pd:Specifications)]'

) = 1

Observe lo siguiente en la consulta anterior:

La cláusula WHERE selecciona únicamente las filas de la tabla ProductDescription que satisfacen la

condición especificada en la columna de tipo CatalogDescription xml.

El método exist() de la cláusula WHERE devuelve 1 (True) si el XML no incluye ningún elemento

<Specifications>. Observe la utilización de la función de XQuery not().

La función de XQuery sql:column() se utiliza para recuperar el valor de una columna distinta de XML.

Esta consulta devuelve un conjunto de filas vacío.

Modify() (método del tipo de datos xml)

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, actualizar o eliminar nodos a

partir de datos XML. El método modify() del tipo de datos xml sólo puede utilizarse en la cláusula SET de una

instrucción UPDATE.

Sintaxis modify (XML_DML)

Argumentos

XML_DML

Es una cadena en lenguaje de manipulación de datos (DML) XML. El documento XML se actualiza

conforme a esta expresión.

Se devuelve un error si se llama al método modify() sobre un valor NULL o da como resultado un valor NULL.

Ejemplos

Puesto que el método modify() requiere una cadena en el lenguaje de manipulación de datos (DML) XML, los

ejemplos de modify() se encuentran en los temas que tratan sobre las instrucciones XML DML. Para consultar

los ejemplos, vea insert (XML DML), delete (XML DML) y replace value of (XML DML).

nodes() (método del tipo de datos XML)

El método nodes() es muy útil si desea dividir una instancia de tipo de datos xml en datos relacionales. Permite

identificar nodos que se asignarán a una fila nueva.

Cada instancia de tipo de datos xml tiene un nodo de contexto proporcionado de manera implícita. 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 implícito situado en la parte superior de cada instancia de tipo de datos xml.

El resultado del método nodes() es un conjunto de datos que contiene copias lógicas de las instancias XML

originales. En estas copias lógicas, el nodo de contexto de cada instancia de fila se establece en uno de los

nodos identificados con la expresión de consulta, de manera que las consultas posteriores pueden desplazarse

de forma relativa hasta estos nodos de contexto.

Puede recuperar varios valores del conjunto de filas. Por ejemplo, puede aplicar el método value() al conjunto

de filas devuelto por nodes() y recuperar varios valores de la instancia XML original. Tenga en cuenta que el

método value(), cuando se aplica a la instancia XML, devuelve sólo un valor.

Sintaxis nodes (XQuery) as Table(Column)

Argumentos

XQuery

Page 14: SQL con XML

Es un literal de cadena, una expresión XQuery. Si la expresión de consulta construye nodos, éstos se

exponen en el conjunto de filas resultante. Si la expresión de consulta da lugar a una secuencia vacía, el

conjunto de filas estará vacío. Si la expresión de consulta da lugar estáticamente a una secuencia que

contiene valores atómicos en lugar de nodos, se produce un error estático.

Table(Column)

Es el nombre de tabla y el nombre de columna del conjunto de filas resultante.

Notas

Por ejemplo, imagine que tiene la tabla siguiente: T (ProductModelID int, Instructions xml)

En la tabla se almacena el siguiente documento de instrucciones de fabricación. Sólo se muestra un fragmento.

Tenga en cuenta que hay tres ubicaciones de fabricación en el documento. <root>

<Location LocationID="10"...>

<step>...</step>

<step>...</step>

...

</Location>

<Location LocationID="20" ...>

...

</Location>

<Location LocationID="30" ...>

...

</Location>

</root>

La invocación del método nodes() con la expresión de consulta /root/Location devuelve un conjunto con tres

filas, de las que cada una contiene una copia lógica del documento XML original, y con el elemento de contexto

establecido en uno de los nodos <Location>: Product

ModelID Instructions

----------------------------------

1 <root>

<Location LocationID="20" ... />

<Location LocationID="30" .../></root>

1 <root><Location LocationID="10" ... />

<Location LocationID="30" .../></root>

1 <root><Location LocationID="10" ... />

<Location LocationID="20" ... />

</root>

A continuación, puede consultar este conjunto de filas utilizando métodos del tipo de datos xml. La siguiente

consulta extrae el subárbol del elemento de contexto de cada fila generada: SELECT T2.Loc.query('.')

FROM T

CROSS APPLY Instructions.nodes('/root/Location') as T2(Loc)

El resultado es el siguiente: ProductModelID Instructions

----------------------------------

1 <Location LocationID="10" ... />

1 <Location LocationID="20" ... />

1 <Location LocationID="30" .../>

Page 15: SQL con XML

Observe que el conjunto de filas devuelto ha mantenido la información de tipo. Puede aplicar métodos del tipo

de datos xml, como query(), value(), exist() y nodes(), al resultado de un método nodes(). Sin embargo, no

puede aplicar el método modify() para modificar la instancia XML.

Asimismo, el nodo de contexto del conjunto de filas no se puede materializar. Es decir, no puede utilizarlo en

una instrucción SELECT. Sin embargo, puede utilizarlo en IS NULL y COUNT(*).

Los escenarios para utilizar el método nodes() son los mismos que para utilizar OPENXML (Transact-SQL). Esto

proporciona una vista del conjunto de filas del documento XML. Sin embargo, no tiene que utilizar cursores

cuando utiliza el método nodes() en una tabla que contenga varias filas de documentos XML.

Observe que el conjunto de filas devuelto por el método nodes() no tiene nombre. Por tanto, se le debe dar un

nombre de manera explícita utilizando alias.

La función nodes() no puede aplicarse directamente a los resultados de una función definida por el usuario.

Para usar la función nodes() con el resultado de una función escalar definida por el usuario, puede asignar el

resultado de la función definida por el usuario a una variable o usar una tabla derivada para asignar un alias de

columna al valor devuelto de la función definida por el usuario y luego usar CROSS APPLY para seleccionar del

alias.

En el ejemplo siguiente se muestra una forma de usar CROSS APPLY para seleccionar entre los resultados de una

función definida por el usuario. USE AdventureWorks;

GO

CREATE FUNCTION XTest()

RETURNS xml

AS

BEGIN

RETURN '<document/>';

END;

GO

SELECT A2.B.query('.')

FROM

(SELECT dbo.XTest()) AS A1(X)

CROSS APPLY X.nodes('.') A2(B);

GO

DROP FUNCTION XTest;

GO

Ejemplos

Usar el método nodes() con una variable de tipo xml

En el siguiente ejemplo, hay un documento XML que incluye un elemento <Root> de nivel superior y tres

elementos secundarios <row>. La consulta utiliza el método nodes() para establecer nodos de contexto

independientes, uno para cada elemento <row>. El método nodes() devuelve un conjunto de tres filas. Cada fila

tiene una copia lógica del documento original, donde cada nodo de contexto identifica un elemento <row>

distinto del documento original.

La consulta devuelve después el nodo de contexto de cada fila: DECLARE @x xml

SET @x='<Root>

<row id="1"><name>Larry</name><oflw>some text</oflw></row>

<row id="2"><name>moe</name></row>

<row id="3" />

</Root>'

Page 16: SQL con XML

SELECT T.c.query('.') AS result

FROM @x.nodes('/Root/row') T(c)

GO

A continuación se muestra el resultado. En este ejemplo, el método de consulta devuelve el elemento de

contexto y su contenido:

<row id="1"><name>Larry</name><oflw>some text</oflw></row> <row id="2"><name>moe</name></row>

<row id="3"/>

Si se aplica el descriptor de acceso primario en los nodos de contexto, devuelve el elemento <Root> para los

tres: SELECT T.c.query('..') AS result

FROM @x.nodes('/Root/row') T(c)

go

El resultado es el siguiente: <Root>

<row id="1"><name>Larry</name><oflw>some text</oflw></row>

<row id="2"><name>moe</name></row>

<row id="3" />

</Root>

<Root>

<row id="1"><name>Larry</name><oflw>some text</oflw></row>

<row id="2"><name>moe</name></row>

<row id="3" />

</Root>

<Root>

<row id="1"><name>Larry</name><oflw>some text</oflw></row>

<row id="2"><name>moe</name></row>

<row id="3" />

</Root>

Especificar el método nodes() con una columna de tipo xml

En este ejemplo se utilizan las instrucciones de fabricación de bicicletas y se almacenan en la columna

Instructions de tipo xml de la tabla ProductModel. Para obtener más información, vea Representación de tipo

de datos xml en la base de datos AdventureWorks.

En el siguiente ejemplo, el método nodes() se especifica para la columna Instructions de tipo xml de la tabla

ProductModel.

El método nodes() establece los elementos <Location> como nodos de contexto especificando la ruta de acceso

/MI:root/MI:Location. El conjunto de filas resultante incluye copias lógicas del documento original, una para

cada nodo <Location> del documento, con el nodo de contexto establecido en el elemento <Location>. Por

tanto, la función nodes() ofrece un conjunto de nodos de contexto <Location>.

El método query() sobre este conjunto de resultados solicita self::node y, por lo tanto, devuelve el elemento

<Location> de cada fila.

En este ejemplo, la consulta establece cada elemento <Location> como un nodo de contexto en el documento

de instrucciones de fabricación del modelo de producto específico. Puede utilizar estos nodos de contexto para

recuperar valores como los siguientes:

Buscar los Id. de ubicación de cada <Location>

Recuperar pasos de fabricación (elementos <step> secundarios) en cada <Location>

Esta consulta devuelve el elemento de contexto, en el que se especifica la sintaxis abreviada '.' para self::node(),

en el método query().

Tenga en cuenta lo siguiente:

Page 17: SQL con XML

El método nodes() se aplica a la columna Instructions y devuelve un conjunto de filas, T (C). Este

conjunto de filas contiene copias lógicas del documento de instrucciones de fabricación original con

/root/Location como elemento de contexto.

CROSS APPLY aplica nodes() a cada fila de la tabla Instructions y devuelve sólo las filas que producen un

conjunto de resultados. SELECT C.query('.') as result

FROM Production.ProductModel

CROSS APPLY Instructions.nodes('

declare namespace MI="http://schemas.microsoft.com/sqlserver/2004/07/adventure-

works/ProductModelManuInstructions";

/MI:root/MI:Location') as T(C)

WHERE ProductModelID=7

Éste es el resultado parcial: <MI:Location LocationID="10" ...>

<MI:step ... />

...

</MI:Location>

<MI:Location LocationID="20" ... >

<MI:step ... />

...

</MI:Location>

...

Aplicar nodes() al conjunto de filas devuelto por otro método nodes()

El código siguiente realiza una consulta en los documentos XML sobre instrucciones de fabricación en la

columna Instructions de la tabla ProductModel. La consulta devuelve un conjunto de filas que contiene el Id. del

modelo de producto, las ubicaciones y los pasos de fabricación.

Tenga en cuenta lo siguiente:

El método nodes() se aplica a la columna Instructions y devuelve el conjunto de filas T1 (Locations). Este

conjunto de filas contiene copias lógicas del documento de instrucciones de fabricación original con el

elemento /root/Location como contexto del elemento.

nodes() se aplica al conjunto de filas T1 (Locations) y devuelve el conjunto de filas T2 (steps). Este

conjunto de filas contiene copias lógicas del documento de instrucciones de fabricación original con el

elemento /root/Location/step como contexto del elemento. SELECT ProductModelID, Locations.value('./@LocationID','int') as LocID,

steps.query('.') as Step

FROM Production.ProductModel

CROSS APPLY Instructions.nodes('

declare namespace MI="http://schemas.microsoft.com/sqlserver/2004/07/adventure-

works/ProductModelManuInstructions";

/MI:root/MI:Location') as T1(Locations)

CROSS APPLY T1.Locations.nodes('

declare namespace MI="http://schemas.microsoft.com/sqlserver/2004/07/adventure-

works/ProductModelManuInstructions";

./MI:step ') as T2(steps)

WHERE ProductModelID=7

GO

El resultado es el siguiente: ProductModelID LocID Step

----------------------------

7 10 <step ... />

7 10 <step ... />

Page 18: SQL con XML

...

7 20 <step ... />

7 20 <step ... />

7 20 <step ... />

...

Enlazar datos relacionales dentro de datos XML

Puede especificar Métodos de tipo de datos xml con una variable de tipo de datos o columna xml. Por ejemplo,

query() (método de tipo de datos xml) ejecuta la instrucción XQuery especificada con una instancia XML.

Cuando se genera XML de esta manera, se puede utilizar un valor de un tipo de columna que no es XML o una

variable Transact-SQL. Este proceso se conoce como enlazar datos relacionales dentro de XML.

Para enlazar datos relacionales no XML dentro de XML, el motor de base de datos de SQL Server proporciona

estas seudofunciones:

sql:column() (función de XQuery). Le permite utilizar los valores de una columna relacional en la

expresión XQuery o XML DML.

sql:variable() (función de XQuery). Le permite utilizar el valor de una variable de SQL en la expresión

XQuery o XML DML.

Estas funciones se pueden utilizar con métodos de tipo de datos xml siempre que se desee exponer un valor

relacional dentro de XML.

Estas funciones no se pueden utilizar para hacer referencia a datos en columnas o variables de tipo xml, de tipos

definidos por el usuario CLR, datetime, smalldatetime, text, ntext, sql_variant e image.

Asimismo, este enlace es de sólo 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 expresión".

Ejemplo: consulta entre dominios mediante sql:variable()

Este ejemplo muestra cómo sql:variable() puede permitir a una aplicación parametrizar una consulta. El ISBN se

pasa mediante una variable SQL @isbn. Sustituyendo la constante por sql:variable(), la consulta sirve para

buscar cualquier ISBN y no sólo el que corresponde a 0-7356-1588-2. DECLARE @isbn varchar(20)

SET @isbn = '0-7356-1588-2'

SELECT xCol

FROM T

WHERE xCol.exist ('/book/@ISBN[. = sql:variable("@isbn")]') = 1

sql:column() se puede utilizar de manera similar y ofrece otras ventajas. Los índices de la columna favorecen la

eficiencia, según lo decida el optimizador de consultas basado en costos. Además, la columna calculada puede

almacenar una propiedad promocionada.

Directrices para utilizar los métodos del tipo de datos xml

En este tema se describen instrucciones para utilizar los métodos de tipo de datos xml.

La instrucción PRINT

Los métodos del tipo de datos xml no se pueden utilizar en la instrucción PRINT, como se muestra en el

ejemplo siguiente. Los métodos del tipo de datos xml se tratan como subconsultas y éstas no están permitidas

en la instrucción PRINT. Como resultado, el ejemplo siguiente devuelve un error: DECLARE @x xml

SET @x = '<root>Hello</root>'

PRINT @x.value('/root[1]', 'varchar(20)') -- will not work because this is treated

as a subquery (select top 1 col from table)

Una solución es asignar primero el resultado del método value() a una variable de tipo xml y, después,

especificar la variable en la consulta. DECLARE @x xml

DECLARE @c varchar(max)

Page 19: SQL con XML

SET @x = '<root>Hello</root>'

SET @c = @x.value('/root[1]', 'varchar(11)')

PRINT @c

La cláusula GROUP BY

Los métodos del tipo de datos xml se tratan internamente como subconsultas. Como GROUP BY requiere un

valor escalar y no permite agregados ni subconsultas, no se pueden especificar los métodos del tipo de datos

xml en la cláusula GROUP BY. Una solución es llamar a una función definida por el usuario que utilice métodos

XML en su interior.

La notificación de errores

Al informar de errores, los métodos del tipo de datos xml generan un único error con el formato siguiente: Msg errorNumber, Level levelNumber, State stateNumber:

XQuery [database.table.method]: description_of_error

Por ejemplo: Msg 2396, Level 16, State 1:

XQuery [xmldb_test.xmlcol.query()]: Attribute may not appear outside of an element

Comprobaciones de singleton

Los pasos de ubicación, los parámetros de funciones y los operadores que requieren singleton devolverán un

error si el compilador no puede determinar si se garantiza un singleton en tiempo de ejecución. Este problema

es frecuente con datos sin tipo. Por ejemplo, la búsqueda de un atributo requiere un elemento primario

singleton. Es suficiente con un ordinal que seleccione un solo nodo primario. Es posible que la evaluación de

una combinación node()-value() para extraer valores de atributos no requiera la especificación del ordinal. Esto

se muestra en el ejemplo siguiente.

Ejemplo: singleton conocido

En este ejemplo, el método nodes() genera una fila distinta para cada elemento <book>. El método value() que

se evalúa en un nodo <book> extrae el valor de @genre y, siendo un atributo, es un singleton. SELECT nref.value('@genre', 'varchar(max)') LastName

FROM T CROSS APPLY xCol.nodes('//book') AS R(nref)

El esquema XML se utiliza para comprobar el tipo del XML con tipo. Si se especifica un nodo como singleton en

el esquema XML, el compilador usa esa información y no se produce ningún error. En caso contrario, se necesita

un ordinal que seleccione un solo nodo. En particular, el uso de ejes descendant-or-self (//), como en

/book//title, pierde inferencia de cardinalidad de singleton para el elemento <title>, incluso si el esquema XML

especifica que sea así. Por tanto, se debe volver a escribir como (/book//title)[1].

Es importante ser consciente de la diferencia entre //first-name[1] y (//first-name)[1] para la comprobación de

tipos. La primera expresión devuelve una secuencia de nodos <first-name> en la que cada nodo es el que está

más a la izquierda entre los de su mismo nivel. La última expresión devuelve el primer nodo singleton <first-

name> por orden de los documentos en la instancia XML.

Ejemplo: utilizar value()

La siguiente consulta en una columna XML sin tipo da como resultado un error de compilación estático. Esto se

debe a que value() espera un nodo singleton como primer argumento y el compilador no puede determinar si

sólo va a aparecer un nodo <last-name> en tiempo de ejecución: SELECT xCol.value('//author/last-name', 'nvarchar(50)') LastName

FROM T

A continuación, se ofrece una solución que debe contemplar: SELECT xCol.value('//author/last-name[1]', 'nvarchar(50)') LastName

FROM T

No obstante, esta solución no resuelve el error, ya que pueden aparecer varios nodos <author> en cada

instancia XML. Resulta útil volver a escribir lo siguiente:

Page 20: SQL con XML

SELECT xCol.value('(//author/last-name/text())[1]', 'nvarchar(50)') LastName

FROM T

Esta consulta devuelve el valor del primer elemento <last-name> de cada instancia XML.

ESTABLECER OPCIONES (TIPO DE DATOS XML)

[Este tema pertenece a la documentación de la versión preliminar y está sujeto a cambios en versiones futuras.

Los temas en blanco se incluyen como marcadores de posición. NOTA: Con el fin de proporcionarle contenido

adicional en distintos idiomas, Microsoft ofrece documentación localizada mediante métodos de traducción

alternativos. Para esta versión preliminar, parte del contenido de esta documentación se ha traducido mediante

el uso de estos métodos. Microsoft es consciente de que los documentos traducidos de esta forma no son

siempre perfectos, por lo que es posible que este artículo contenga errores de vocabulario, sintaxis o gramática.

La versión final de este contenido se traducirá por los métodos tradicionales y la calidad será igual que la de las

versiones anteriores.]

Cuando se consultan variables o columnas de tipo xml utilizando métodos del tipo de datos xml, se deben

establecer las siguientes opciones como se indica.

Opciones SET Valores requeridos

ANSI_NULLS ON

ANSI_PADDING ON

ANSI_WARNINGS ON

ARITHABORT ON

CONCAT_NULL_YIELDS_NULL ON

NUMERIC_ROUNDABORT OFF

QUOTED_IDENTIFIER ON

Si no se establecen las opciones como se indica, no funcionarán las consultas y modificaciones de los métodos

del tipo de datos xml.

LENGUAJE DE MANIPULACIÓN DE DATOS XML (XML DML)

El Lenguaje de manipulación de datos XML (XML DML) es una extensión del lenguaje XQuery1. Según W3C, el

lenguaje XQuery carece de la parte de manipulación de datos (DML). El lenguaje XML DML que se presenta en

1 Soporte XQuery

El Lenguaje XML Query, o XQuery, es un lenguaje inteligente y robusto optimizado para la consulta de todos los tipos de datos XML. Con

XQuery, usted puede correr procesos de consultas contra variables y columnas de tipos de datos XML utilizando los últimos métodos de

asociación. Como muchos de los estándares XML, el World Wide Web Consortium (W3C) supervisa el desarrollo de XQuery. XQuery ha

evolucionado de un lenguaje llamado Quilt, el cual estaba basado en una variedad de otros lenguajes de consulta como por ejemplo XML

Path Language (XPath) versión 1.0, XQL, y SQL. Tambien contiene XPath 2.0 como un subgrupo. Por lo tanto, si usted tenía experiencia

utilizando XPath 1.0, puede capitalizar sus habilidades y no tendrá que aprender el nuevo lenguaje por completo. Sin embargo, existen

Page 21: SQL con XML

este tema, así como el lenguaje XQuery, proporciona un lenguaje de consultas y modificación de datos

completamente funcional que se puede utilizar con el tipo de datos xml.

La especificación XQuery actualmente contiene sintaxis y semántica para consultas, pero no para modificar

documentos XML. El XML Data Modification Language (DML) es una extensión de las características de XQuery

para modificación de datos. SQL Server 2005 Beta 2 incorpora tres palabras claves: insert, update, y delete. Cada

una de estas tres se utiliza dentro del método

modify() del tipo de datos XML.

XML DML agrega a XQuery las siguientes palabras clave, donde se distingue entre mayúsculas y minúsculas:

insert

delete

replace value of

Como se describe en Tipo de datos XML, se pueden crear variables y columnas de tipo xml y asignarles

documentos o fragmentos XML. Para modificar o actualizar estas instancias XML, realice el siguiente

procedimiento:

Utilice el método modify() del tipo de datos xml.

Especifique las instrucciones XML DML correspondientes en el método modify().

Tenga en cuenta que no se pueden insertar ni eliminar algunos atributos, y a veces tampoco es posible

modificar sus valores. Por ejemplo:

Para xml con tipo o sin tipo, los atributos son xmlns, xmlns:* y xml:base.

Sólo para xml con tipo, los atributos son xsi:nil y xsi:type.

Entre otras restricciones se pueden citar las siguientes:

Para xml con o sin tipo, se producirá un error al insertar el atributo xml:base.

Para xml con tipo, se producirá un error al eliminar y modificar el atributo xsi:nil. Para xml sin tipo, se

puede eliminar el atributo o modificar su valor.

Para xml con tipo, se producirá un error si se modifica el valor del atributo xs:type. Para xml sin tipo, se

puede modificar el valor del atributo.

Cuando se modifica una instancia XML con tipo, el formato final debe ser una instancia válida de ese tipo. En

caso contrario, se devuelve un error de validación.

INSERT

Inserta uno o más nodos identificados por Expression1 como nodos secundarios o del mismo nivel que el nodo

identificado por Expression2.

Sintaxis: insert

Expression1 (

{as first | as last} into | after | before

Expression2

)

Argumentos:

Expression1

Identifica uno o varios nodos que se van a insertar. Puede ser una instancia XML constante; una

referencia a una instancia del tipo de datos XML con tipo de la misma colección de esquemas XML en el

mejoras significativas que van más allá de XPath 1.0, como por ejemplo tipeo, funciones especiales, y soporte para mejor iteración, orden de

resultados, y construcción.

Page 22: SQL con XML

que se aplica el método modify; una instancia del tipo de datos XML sin tipo que utiliza una función

sql:column()/sql:variable() independiente; o una expresión XQuery. La expresión puede proporcionar un

nodo, y también un nodo de texto, o una secuencia ordenada de nodos. No se puede resolver en el

nodo raíz (/). Si la expresión da como resultado un valor o una secuencia de valores, los valores se

insertan como un solo nodo de texto y cada valor de la secuencia se separa con un espacio. Si se

especifican varios nodos como constante, los nodos se incluyen entre paréntesis y se separan mediante

comas. No es posible insertar secuencias heterogéneas, como una secuencia de elementos, atributos o

valores. Si Expression1 se resuelve en una secuencia vacía, no se produce ninguna inserción ni se

devuelven errores.

into

Los nodos identificados por Expression1 se insertan como descendientes directos (nodos secundarios)

del nodo identificado por Expression2. Si el nodo de Expression2 ya tiene uno o más nodos secundarios,

se debe utilizar as first o as last para especificar dónde se desea agregar el nuevo nodo. Se agregaría al

principio o al final de la lista de nodos secundarios respectivamente. Las palabras clave as first y as last

se omiten cuando se insertan atributos.

after

Los nodos identificados por Expression1 se insertan como nodos del mismo nivel justo después del

nodo identificado por Expression2. La palabra clave after no se puede utilizar para insertar atributos. Por

ejemplo, no se puede utilizar para insertar un constructor de atributos o devolver un atributo desde una

consulta XQuery.

before

Los nodos identificados por Expression1 se insertan como nodos del mismo nivel justo antes del nodo

identificado por Expression2. La palabra clave before no se puede utilizar cuando se insertan atributos.

Por ejemplo, no se puede utilizar para insertar un constructor de atributos o devolver un atributo desde

una consulta XQuery.

Expression2

Identifica un nodo. Los nodos identificados en Expression1 se insertan con respecto al nodo identificado

por Expression2. Puede ser una expresión XQuery que devuelva una referencia a un nodo que exista en

el documento al que se hace referencia actualmente. Si se devuelve más de un nodo, se produce un

error en la operación de inserción. Si Expression2 devuelve una secuencia vacía, no se produce ninguna

inserción ni se devuelven errores. Si Expression2 no es un singleton de manera estática, se devuelve un

error estático. Expression2 no puede ser una instrucción de procesamiento, un comentario ni un

atributo. Tenga en cuenta que Expression2 debe ser una referencia a un nodo existente en el documento

y no a un nodo construido.

DELETE

Elimina nodos de una instancia XML.

Sintaxis: delete Expression

Argumentos:

Expression

Es una expresión XQuery que identifica los nodos que se deben eliminar. Se eliminarán todos los nodos

seleccionados por la expresión y los nodos o valores incluidos en los mismos. Tal como se describe en

insert (XML DML), debe ser una referencia a un nodo existente en el documento. No puede ser un nodo

construido. La expresión no puede ser el nodo raíz (/). Si la expresión devuelve una secuencia vacía, no

se produce ninguna eliminación y no se devuelven errores.

Page 23: SQL con XML

REPLACE VALUE OF

Actualiza el valor de un nodo en el documento.

Sintaxis: replace value of

Expression1

with

Expression2

Argumentos:

Expression1

Identifica un nodo cuyo valor se va a actualizar. Debe identificar un solo nodo. Es decir, Expression1

debe ser un singleton estático. Si el XML tiene un tipo, el tipo del nodo debe ser simple. Si se

seleccionan varios nodos, se producirá un error. Si Expression1 devuelve una secuencia vacía, no se

reemplazará ningún valor y no se devolverá ningún error. Expression1 debe devolver un solo elemento

que incluya contenido de tipo simple (tipos de lista o atómicos), un nodo de texto o un nodo de

atributo. Expression1 no puede ser un tipo de unión, un tipo complejo, una instrucción de

procesamiento, un nodo de documento ni un nodo de comentario. De lo contrario, se devolverá un

error.

Expression2

Identifica el nuevo valor del nodo. Puede ser una expresión que devuelve un nodo de tipo simple,

puesto que se utilizará data() implícitamente. Si el valor es una lista de valores, la instrucción update

reemplazará el valor antiguo por la lista. Si se modifica una instancia XML con tipo, Expression2 debe ser

del mismo tipo o un subtipo de Expression1. De lo contrario, se devolverá un error. Si se modifica una

instancia XML sin tipo, Expression2 debe ser una expresión que se pueda atomizar. En caso contrario, se

devolverá un error.

TRABAJAR CON EL TIPO DE DATOS XML EN APLICACIONES

Controlar XML desde una columna de tipo XML usando ADO y SQL Server Native Client

Para usar componentes MDAC con el fin de obtener acceso a los tipos y características introducidos en SQL

Server 2005, debe establecer la propiedad de inicialización DataTypeCompatibility en la cadena de conexión

de ADO.

Por ejemplo, en el siguiente ejemplo de Visual Basic Scripting Edition (VBScript) se muestra el resultado de la

realización de una consulta a una columna de tipo de datos xml, Demographics, de la tabla Sales.Store de la

base de datos de ejemplo AdventureWorks. Específicamente, la consulta busca el valor de la instancia de esta

columna para la fila en la que CustomerID es igual a 3.

Const DS = "MyServer"

Const DB = "AdventureWorks"

Set objConn = CreateObject("ADODB.Connection")

Set objRs = CreateObject("ADODB.Recordset")

CommandText = "SELECT Demographics" & _

" FROM Sales.Store" & _

" WHERE CustomerID = 3" & _

" OR CustomerID = 4"

Page 24: SQL con XML

ConnectionString = "Provider=SQLNCLI10" & _

";Data Source=" & DS & _

";Initial Catalog=" & DB & _

";Integrated Security=SSPI;" & _

"DataTypeCompatibility=80"

'Connect to the data source.

objConn.Open ConnectionString

'Execute command through the connection and display

Set objRs = objConn.Execute(CommandText)

Dim rowcount

rowcount = 0

Do While Not objRs.EOF

rowcount = rowcount + 1

MsgBox "Row " & rowcount & _

vbCrLf & vbCrLf & objRs(0)

objRs.MoveNext

Loop

'Clean up.

objRs.Close

objConn.Close

Set objRs = Nothing

Set objConn = Nothing

Este ejemplo muestra cómo establecer la propiedad de compatibilidad de tipos de datos. De manera

predeterminada, se establece en 0 cuando se usa SQL Server Native Client. Después de establecer el valor en 80,

el proveedor de SQL Server Native Client hará que las columnas de tipo xml y las definidas por el usuario

aparezcan como tipos de datos de SQL Server 2000. Serán DBTYPE_WSTR y DBTYPE_BYTES, respectivamente.

SQL Server Native Client también debe estar instalado en el equipo cliente y la cadena de conexión debe

especificar que se use como proveedor de datos con "Provider=SQLNCLI10;...".

Para probar este ejemplo

1. Compruebe que SQL Server Native Client está instalado y que en el equipo cliente está disponible

MDAC 2.6 o versiones posteriores.

2. Compruebe que la base de datos de ejemplo AdventureWorks de SQL Server está instalada.

3. Copie el código que se mostró anteriormente en este tema y péguelo en su editor de texto o de código.

Guarde el archivo como HandlingXmlDataType.vbs.

4. Modifique la secuencia de comandos según sea necesario por la instalación de SQL Server y guarde los

cambios.

Por ejemplo, donde se especifique MyServer, debe sustituirlo por (local) o por el nombre real del

servidor en el que está instalado SQL Server.

5. Ejecute HandlingXmlDataType.vbs y ejecute la secuencia de comandos.

Los resultados serán similares a los de la siguiente salida de ejemplo:

Row 1

<StoreSurvey xmlns="http://schemas.microsoft.com/sqlserver/2004/07/adventure-

works/StoreSurvey">

<AnnualSales>1500000</AnnualSales>

<AnnualRevenue>150000</AnnualRevenue>

<BankName>Primary International</BankName>

Page 25: SQL con XML

<BusinessType>OS</BusinessType>

<YearOpened>1974</YearOpened>

<Specialty>Road</Specialty>

<SquareFeet>38000</SquareFeet>

<Brands>3</Brands>

<Internet>DSL</Internet>

<NumberEmployees>40</NumberEmployees>

</StoreSurvey>

Row 2

<StoreSurvey xmlns="http://schemas.microsoft.com/sqlserver/2004/07/adventure-

works/StoreSurvey">

<AnnualSales>300000</AnnualSales>

<AnnualRevenue>30000</AnnualRevenue>

<BankName>United Security</BankName>

<BusinessType>BM</BusinessType>

<YearOpened>1976</YearOpened>

<Specialty>Road</Specialty>

<SquareFeet>6000</SquareFeet>

<Brands>2</Brands>

<Internet>DSL</Internet>

<NumberEmployees>5</NumberEmployees>

</StoreSurvey>

Controlar XML desde una columna de tipo xml utilizando ADO.NET

Para controlar XML desde una columna de tipo de datos xml utilizando ADO.NET y Microsoft .NET Framework,

puede utilizar el comportamiento estándar de la clase SqlCommand. Por ejemplo, una columna de tipo de

datos xml y sus valores se pueden recuperar de la misma manera que se recupera cualquier columna SQL

utilizando una clase SqlDataReader. Sin embargo, si desea trabajar con el contenido de una columna de tipo de

datos xml como XML, primero tendrá que asignar el contenido a un tipo XmlReader.

Controlar una columna de tipo XML como parámetros mediante ADO.NET

Para controlar un tipo de datos XML pasado como un parámetro en ADO.NET y .NET Framework, puede

proporcionar el valor como una instancia del tipo de datos SqlXml. No es necesario realizar ningún control

especial, porque las columnas de tipo de datos xml de SQL Server pueden aceptar valores de parámetros del

mismo modo que otros tipos de columnas y de datos, por ejemplo, string o integer.

REPRESENTACIÓN DE TIPO DE DATOS XML EN LA BASE DE DATOS ADVENTUREWORKS

La base de datos AdventureWorks tiene varias columnas de tipo xml. La siguiente tabla muestra los temas de

esta sección que describen estas columnas. Estas columnas se utilizan en varias consultas de ejemplo de los

Libros en pantalla de SQL Server.

Cada tema proporciona una instancia de ejemplo de datos XML almacenados en las columnas. La mayoría son

columnas XML con tipo. Estos temas ofrecen la colección de esquemas XML que se utiliza para escribir estas

columnas. Para entender las consultas especificadas, debe revisar los datos XML almacenados en estas

columnas.

Para ver cada una de los esquemas de la base AdventureWorks se puede utilizar USE AdventureWorks

Page 26: SQL con XML

GO

SELECT *

FROM sys.xml_schema_collections

Resultado obtenido:

AdditionalContactInfoSchemaCollection

IndividualSurveySchemaCollection

HRResumeSchemaCollection

ProductDescriptionSchemaCollection

ManuInstructionsSchemaCollection

StoreSurveySchemaCollection

Para ver los tipos de cada esquema XML utilice SELECT xml_schema_namespace(N'Person',N'AdditionalContactInfoSchemaCollection')

GO

SELECT xml_schema_namespace(N'Sales',N'IndividualSurveySchemaCollection')

GO

SELECT xml_schema_namespace(N'HumanResources',N'HRResumeSchemaCollection')

GO

SELECT xml_schema_namespace(N'Production',N'ProductDescriptionSchemaCollection')

Go

SELECT xml_schema_namespace(N'Production',N'ManuInstructionsSchemaCollection')

GO

SELECT xml_schema_namespace(N'Sales',N'StoreSurveySchemaCollection')

GO

La salida será un esquema XML, este es el ejemplo para el AditionalContactInfoSchemaColection <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"

xmlns:t="http://schemas.microsoft.com/sqlserver/2004/07/adventure-

works/ContactInfo"

targetNamespace="http://schemas.microsoft.com/sqlserver/2004/07/adventure-

works/ContactInfo">

<xsd:element name="AdditionalContactInfo">

<xsd:complexType mixed="true">

<xsd:complexContent mixed="true">

<xsd:restriction base="xsd:anyType">

<xsd:sequence>

<xsd:any

namespace="http://schemas.microsoft.com/sqlserver/2004/07/adventure-

works/ContactRecord http://schemas.microsoft.com/sqlserver/2004/07/adventure-

works/ContactTypes" minOccurs="0" maxOccurs="unbounded" />

</xsd:sequence>

</xsd:restriction>

</xsd:complexContent>

</xsd:complexType>

</xsd:element>

</xsd:schema>

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"

xmlns:t="http://schemas.microsoft.com/sqlserver/2004/07/adventure-

works/ContactRecord"

targetNamespace="http://schemas.microsoft.com/sqlserver/2004/07/adventure-

works/ContactRecord">

<xsd:element name="ContactRecord">

<xsd:complexType mixed="true">

<xsd:complexContent mixed="true">

<xsd:restriction base="xsd:anyType">

Page 27: SQL con XML

<xsd:choice minOccurs="0" maxOccurs="unbounded">

<xsd:any

namespace="http://schemas.microsoft.com/sqlserver/2004/07/adventure-

works/ContactTypes" />

</xsd:choice>

<xsd:attribute name="date" type="xsd:date" />

</xsd:restriction>

</xsd:complexContent>

</xsd:complexType>

</xsd:element>

</xsd:schema>

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"

xmlns:t="http://schemas.microsoft.com/sqlserver/2004/07/adventure-

works/ContactTypes"

targetNamespace="http://schemas.microsoft.com/sqlserver/2004/07/adventure-

works/ContactTypes" elementFormDefault="qualified">

<xsd:element name="eMail" type="t:eMailType" />

<xsd:element name="facsimileTelephoneNumber" type="t:phoneNumberType" />

<xsd:element name="homePostalAddress" type="t:addressType" />

<xsd:element name="internationaliSDNNumber" type="t:phoneNumberType" />

<xsd:element name="mobile" type="t:phoneNumberType" />

<xsd:element name="pager" type="t:phoneNumberType" />

<xsd:element name="physicalDeliveryOfficeName" type="t:addressType" />

<xsd:element name="registeredAddress" type="t:addressType" />

<xsd:element name="telephoneNumber" type="t:phoneNumberType" />

<xsd:element name="telexNumber" type="t:phoneNumberType" />

<xsd:complexType name="addressType">

<xsd:complexContent>

<xsd:restriction base="xsd:anyType">

<xsd:sequence>

<xsd:element name="Street" type="xsd:string" maxOccurs="2" />

<xsd:element name="City" type="xsd:string" />

<xsd:element name="StateProvince" type="xsd:string" />

<xsd:element name="PostalCode" type="xsd:string" minOccurs="0" />

<xsd:element name="CountryRegion" type="xsd:string" />

<xsd:element name="SpecialInstructions" type="t:specialInstructionsType"

minOccurs="0" />

</xsd:sequence>

</xsd:restriction>

</xsd:complexContent>

</xsd:complexType>

<xsd:complexType name="eMailType">

<xsd:complexContent>

<xsd:restriction base="xsd:anyType">

<xsd:sequence>

<xsd:element name="eMailAddress" type="xsd:string" />

<xsd:element name="SpecialInstructions" type="t:specialInstructionsType"

minOccurs="0" />

</xsd:sequence>

</xsd:restriction>

</xsd:complexContent>

</xsd:complexType>

<xsd:complexType name="phoneNumberType">

<xsd:complexContent>

<xsd:restriction base="xsd:anyType">

<xsd:sequence>

<xsd:element name="number">

Page 28: SQL con XML

<xsd:simpleType>

<xsd:restriction base="xsd:string">

<xsd:pattern value="[0-9\(\)\-]*" />

</xsd:restriction>

</xsd:simpleType>

</xsd:element>

<xsd:element name="SpecialInstructions" type="t:specialInstructionsType"

minOccurs="0" />

</xsd:sequence>

</xsd:restriction>

</xsd:complexContent>

</xsd:complexType>

<xsd:complexType name="specialInstructionsType" mixed="true">

<xsd:complexContent mixed="true">

<xsd:restriction base="xsd:anyType">

<xsd:sequence>

<xsd:any

namespace="http://schemas.microsoft.com/sqlserver/2004/07/adventure-

works/ContactTypes" minOccurs="0" maxOccurs="unbounded" />

</xsd:sequence>

</xsd:restriction>

</xsd:complexContent>

</xsd:complexType>

</xsd:schema>