Usar tipos de datos XML
Se aplica a: SQL Server Azure SQL Database Azure SQL Managed Instance Azure Synapse Analytics Analytics Platform System (PDW)
En SQL Server 2005 (9.x), se ha introducido un tipo de datos xml que permite almacenar fragmentos y documentos XML en una base de datos de SQL Server. El tipo de datos xml es un tipo de datos integrado en SQL Server y es de algún modo similar a otros tipos integrados, como int y varchar. Al igual que ocurre con otros tipos integrados, el tipo de datos xml puede usarse 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 funciones CAST y CONVERT.
Consideraciones sobre la programación
El XML puede ser autodescriptivo ya que puede incluir un encabezado XML que especifique la codificación del documento como, por ejemplo:
<?xml version="1.0" encoding="windows-1252"?><doc/>
El estándar XML describe la forma en que un procesador XML puede detectar la codificación usada en un documento examinando los primeros bytes del documento. Hay ocasiones en que la codificación especificada por la aplicación entra en conflicto con la codificación especificada por el documento. En el caso de los documentos que se pasan como parámetros enlazados, SQL Server trata el XML como datos binarios, por lo que no se realiza ninguna conversión y el analizador XML puede usar la codificación especificada en el documento sin problemas. Sin embargo, en el caso de los datos XML enlazados como WSTR, la aplicación debe asegurarse de que el documento esté codificado como Unicode. En este escenario, puede que sea necesario cargar el documento en un DOM, cambiar la codificación a Unicode y serializar el documento. Si no se completa este paso, pueden producirse conversiones de datos, lo que daría lugar a un XML no válido o dañado.
También pueden surgir conflictos cuando el XML se especifica en literales. Por ejemplo, las siguientes instrucciones no son válidas:
INSERT INTO xmltable(xmlcol) VALUES('<?xml version="1.0" encoding="UTF-16"?><doc/>')
INSERT INTO xmltable(xmlcol) VALUES(N'<?xml version="1.0" encoding="UTF-8"?><doc/>')
Controlador OLE DB para SQL Server
DBTYPE_XML es un nuevo tipo de datos específico de XML de OLE DB Driver for SQL Server. Además, puede obtenerse acceso a los datos XML a través de los tipos OLE DB existentes DBTYPE_BYTES, DBTYPE_WSTR, DBTYPE_BSTR, DBTYPE_XML, DBTYPE_STR, DBTYPE_VARIANT y DBTYPE_IUNKNOWN. Los datos almacenados en columnas de tipo XML pueden recuperarse de una columna de un conjunto de filas del controlador OLE DB para SQL Server con los formatos siguientes:
Una cadena de texto
Un elemento ISequentialStream
Nota:
En el controlador OLE DB para SQL Server no se incluye un lector SAX, pero el elemento ISequentialStream puede pasarse fácilmente a los objetos SAX y DOM en MSXML.
Para recuperar documentos XML de gran tamaño, es necesario usar el elemento ISequentialStream. Las mismas técnicas que se usan para otros tipos de valores grandes también se aplican a XML. Para más información, consulte Usar tipos de valor grande.
Una aplicación también puede recuperar, insertar o actualizar datos almacenados en columnas de tipo XML de un conjunto de filas mediante las interfaces habituales, como IRow::GetColumns, IRowChange::SetColumns e ICommand::Execute. Al igual que ocurre en la recuperación, un programa de aplicación puede pasar una cadena de texto o una interfaz ISequentialStream al controlador OLE DB para SQL Server.
Nota:
Para enviar datos XML en formato de cadena mediante la interfaz ISequentialStream, tiene que obtener ISequentialStream especificando DBTYPE_IUNKNOWN y establecer su argumento pObject en NULL en el enlace.
Cuando los datos XML recuperados se truncan debido a que el búfer del consumidor es demasiado pequeño, la longitud puede devolverse como 0xffffffff, lo que significa que no se conoce la longitud. Este comportamiento es coherente con su implementación como un tipo de datos que se descarga por streaming en el cliente sin enviar la información de longitud antes que los datos reales. En algunos casos, puede devolverse la longitud real cuando el proveedor ha almacenado en el búfer el valor completo (como IRowset::GetData) y cuando se realiza una conversión de datos.
El servidor trata los datos XML enviados a SQL Server como datos binarios. Este comportamiento impide que se produzcan conversiones y permite al analizador XML identificar automáticamente la codificación XML. De esta forma puede aceptarse una mayor variedad de documentos XML como entrada para SQL Server (por ejemplo, los documentos codificados en UTF-8).
Si el XML de entrada se enlaza como DBTYPE_WSTR, la aplicación debe asegurarse de que se trata de Unicode codificado para evitar cualquier posibilidad de que se produzcan daños a causa de conversiones de datos no deseadas.
Enlaces y conversiones de datos
En la tabla siguiente, se describen el enlace y la coerción que tienen lugar al usar los tipos de datos enumerados con el tipo de datos SQL Serverxmlde.
Tipo de datos | A datos XML XML |
A datos XML Distinto de XML |
Desde datos XML XML |
Desde datos XML Distinto de XML |
---|---|---|---|---|
DBTYPE_XML | Paso a través6,7 | Error1 | Correcto11, 6 | Error8 |
DBTYPE_BYTES | Paso a través6,7 | N/D2 | Correcto11, 6 | N/D 2 |
DBTYPE_WSTR | Paso a través6,10 | N/D 2 | Correcto4, 6, 12 | N/D 2 |
DBTYPE_BSTR | Paso a través6,10 | N/D 2 | Correcto3 | N/D 2 |
DBTYPE_STR | Correcto6, 9, 10 | N/D 2 | Correcto5, 6, 12 | N/D 2 |
DBTYPE_IUNKNOWN | Flujo de bytes mediante ISequentialStream7 | N/D 2 | Flujo de bytes mediante ISequentialStream11 | N/D 2 |
DBTYPE_VARIANT (VT_UI1 | VT_ARRAY) | Paso a través6,7 | N/D 2 | N/D | N/D 2 |
DBTYPE_VARIANT (VT_BSTR) | Paso a través6,10 | N/D 2 | Correcto3 | N/D 2 |
1Si se especifica un tipo de servidor distinto de DBTYPE_XML con ICommandWithParameters::SetParameterInfo y el tipo de descriptor de acceso es DBTYPE_XML, se produce un error cuando se ejecuta la instrucción (DB_E_ERRORSOCCURRED, el estado del parámetro es DBSTATUS_E_BADACCESSOR); de lo contrario, los datos se envían al servidor, pero este devuelve un error que indica que no hay ninguna conversión implícita de XML al tipo de datos del parámetro.
2Más allá del ámbito de este artículo.
3Formato UTF-16, sin marca de orden de bytes (BOM), sin especificación de codificación, sin terminación NULL.
4Formato UTF-16, sin marca BOM, sin especificación de codificación, con terminación NULL.
5Formato de caracteres multibyte codificados en la página de códigos de cliente con terminador NULL. La conversión a Unicode proporcionada por el servidor puede producir daños en los datos, por lo que no se recomienda usar este enlace.
6Puede usarse BY_REF.
7Los datos UTF-16 tienen que empezar con una marca BOM. Si no es así, es posible que el servidor no reconozca correctamente la codificación.
8La validación puede producirse en el momento de creación del descriptor de acceso o en el momento de la captura. El error es DB_E_ERRORSOCCURRED, con el estado de enlace establecido en DBBINDSTATUS_UNSUPPORTEDCONVERSION.
9Los datos se convierten a Unicode con la página de códigos del cliente antes de enviarse al servidor. Si la codificación del documento no coincide con la página de códigos del cliente, pueden producirse daños en los datos, por lo que no se recomienda usar este enlace.
10Siempre se agrega la marca BOM a los datos enviados al servidor. Si los datos ya empezaban con una marca BOM, habrá dos marcas BOM al inicio del búfer. El servidor usa la primera marca BOM para reconocer la codificación como UTF-16 y, después, la descarta. La segunda marca se interpreta como un carácter de espacio de no separación de ancho cero.
11Formato UTF-16 sin especificación de codificación, se agrega una marca BOM a los datos recibidos del servidor. Aunque el servidor devuelva una cadena vacía, se devuelve una marca BOM a la aplicación. Si la longitud del búfer es un número de bytes impar, los datos se truncan correctamente. Si el valor completo se devuelve en fragmentos, estos pueden concatenarse para reconstituir el valor correcto.
12Si la longitud del búfer es inferior a dos caracteres (es decir, si no hay espacio suficiente para la terminación NULL), se notifica un error de desbordamiento.
Nota:
Los valores XML NULL no devuelven ningún dato.
El estándar XML exige que el XML con codificación UTF-16 comience con una marca de orden de bytes (BOM), el código de carácter UTF-16 0xFEFF. Cuando se trabaja con enlaces WSTR y BSTR, el controlador OLE DB para SQL Server no necesita ni agrega una marca BOM, ya que la codificación se obtiene del enlace. Cuando se trabaja con enlaces BYTES, XML o IUNKNOWN, se intenta proporcionar simplicidad a la hora de actuar con otros sistemas de almacenamiento y procesadores XML. En este caso, se necesita una marca BOM en el XML con codificación UTF-16 y la aplicación no necesita conocer la codificación real, ya que la mayoría de los procesadores XML (incluido SQL Server) deducen la codificación inspeccionando los primeros bytes del valor. Los datos XML recibidos del controlador OLE DB para SQL Server que usan enlaces BYTES, XML o IUNKNOWN siempre se codifican en UTF-16 con una marca BOM y sin declaración de codificación insertada.
Las conversiones de datos que proporcionan los servicios principales de OLE DB (IDataConvert) no pueden aplicarse en DBTYPE_XML.
La validación se lleva a cabo cuando los datos se envían al servidor. La aplicación debe controlar la validación del lado cliente y los cambios de codificación. Se recomienda no procesar los datos XML directamente, sino que en su lugar debe usar un lector DOM o SAX para procesarlos.
DBTYPE_NULL y DBTYPE_EMPTY pueden enlazarse en parámetros de entrada, pero no en parámetros de salida ni en resultados. Cuando se enlazan para parámetros de entrada, el estado debe establecerse en DBSTATUS_S_ISNULL o DBSTATUS_S_DEFAULT.
DBTYPE_XML puede convertirse en DBTYPE_EMPTY y DBTYPE_NULL, DBTYPE_EMPTY puede convertirse en DBTYPE_XML, pero DBTYPE_NULL no puede convertirse en DBTYPE_XML. Este comportamiento es coherente con el de DBTYPE_WSTR.
DBTYPE_IUNKNOWN es un enlace compatible (como se mostraba en la tabla anterior), pero no hay ninguna conversión entre DBTYPE_XML y DBTYPE_IUNKNOWN. DBTYPE_IUNKNOWN no puede usarse con DBTYPE_BYREF.
Adiciones y cambios en los conjuntos de filas de OLE DB
OLE DB Driver for SQL Server agrega nuevos valores o cambios a muchos de los conjuntos de filas de esquema básicos de OLE DB.
Los conjuntos de filas de esquema COLUMNS y PROCEDURE_PARAMETERS
En las adiciones a los conjuntos de filas de esquema COLUMNS y PROCEDURE_PARAMETERS, se incluyen las columnas siguientes:
Nombre de la columna | Tipo | Descripción |
---|---|---|
SS_XML_SCHEMACOLLECTION_CATALOGNAME | DBTYPE_WSTR | Nombre del catálogo donde se define una colección de esquemas XML. Es NULL para una columna no XML o una columna XML sin tipo. |
SS_XML_SCHEMACOLLECTION_SCHEMANAME | DBTYPE_WSTR | Nombre de un esquema donde se define una colección de esquemas XML. Es NULL para una columna no XML o una columna XML sin tipo. |
SS_XML_SCHEMACOLLECTIONNAME | DBTYPE_WSTR | Nombre de la colección de esquemas XML. Es NULL para una columna no XML o una columna XML sin tipo. |
El conjunto de filas de esquema PROVIDER_TYPES
En el conjunto de filas de esquema PROVIDER_TYPES, el valor de COLUMN_SIZE es 0 para el tipo de datos xml y DATA_TYPE es DBTYPE_XML.
El conjunto de filas de esquema SS_XMLSCHEMA
Se ha introducido un nuevo conjunto de filas de esquema SS_XMLSCHEMA para que los clientes recuperen información del esquema XML. El conjunto de filas SS_XMLSCHEMA contiene las columnas siguientes:
Nombre de la columna | Tipo | Descripción |
---|---|---|
SCHEMACOLLECTION_CATALOGNAME | DBTYPE_WSTR | Catálogo al que pertenece una colección XML. |
SCHEMACOLLECTION_SCHEMANAME | DBTYPE_WSTR | Esquema al que pertenece una colección XML. |
SCHEMACOLLECTIONNAME | DBTYPE_WSTR | Nombre de una colección de esquemas XML para columnas XML con tipo; de lo contrario, NULL. |
TARGETNAMESPACEURI | DBTYPE_WSTR | Espacio de nombres de destino de un esquema XML. |
SCHEMACONTENT | DBTYPE_WSTR | Contenido del esquema XML. |
Los esquemas XML tienen como ámbito el nombre del catálogo, el nombre de esquema, el nombre de la colección de esquemas y el identificador uniforme de recursos (URI) del espacio de nombres de destino. También se define un nuevo GUID con el nombre DBSCHEMA_XML_COLLECTIONS. El número de restricciones y las columnas restringidas del conjunto de filas de esquema SS_XMLSCHEMA se definen tal y como se indica a continuación.
GUID | Número de restricciones | Columnas restringidas |
---|---|---|
DBSCHEMA_XML_COLLECTIONS | 4 | SCHEMACOLLECTION_CATALOGNAME SCHEMACOLLECTION_SCHEMANAME SCHEMACOLLECTIONNAME TARGETNAMESPACEURI |
Adiciones y cambios en los conjuntos de propiedades de OLE DB
OLE DB Driver for SQL Server agrega nuevos valores o cambios a muchos de los conjuntos de propiedades básicos de OLE DB.
El conjunto de propiedades DBPROPSET_SQLSERVERPARAMETER
Para admitir el tipo de datos xml mediante OLE DB, el controlador OLE DB para SQL Server implementa el nuevo conjunto de propiedades DBPROPSET_SQLSERVERPARAMETER, que contiene los valores siguientes.
Nombre | Escribir | Descripción |
---|---|---|
SSPROP_PARAM_XML_SCHEMACOLLECTION_CATALOGNAME | DBTYPE_WSTR | Nombre del catálogo (base de datos) donde se define una colección de esquemas XML. Una de las partes del identificador de nombre de tres partes de SQL. |
SSPROP_PARAM_XML_SCHEMACOLLECTION_SCHEMANAME | DBTYPE_WSTR | Nombre de un esquema XML de la colección de esquemas. Una de las partes del identificador de nombre de tres partes de SQL. |
SSPROP_PARAM_XML_SCHEMACOLLECTIONNAME | DBTYPE_WSTR | Nombre de la colección de esquemas XML del catálogo. Una de las partes del identificador de nombre de tres partes de SQL. |
El conjunto de propiedades DBPROPSET_SQLSERVERCOLUMN
Para admitir la creación de tablas en la interfaz ITableDefinition, el controlador OLE DB para SQL Server agrega las siguientes tres nuevas columnas al conjunto de propiedades DBPROPSET_SQLSERVERCOLUMN.
Nombre | Escribir | Descripción |
---|---|---|
SSPROP_COL_XML_SCHEMACOLLECTION_CATALOGNAME | VT_BSTR | Para las columnas XML con tipo, esta propiedad es una cadena que especifica el nombre del catálogo donde se almacena el esquema XML. Para otros tipos de columna, esta propiedad devuelve una cadena vacía. |
SSPROP_COL_XML_SCHEMACOLLECTION_SCHEMANAME | VT_BSTR | Para las columnas XML con tipo, esta propiedad es una cadena que especifica el nombre del esquema XML que define esta columna. |
SSPROP_COL_XML_SCHEMACOLLECTIONNAME | VT_BSTR | Para las columnas XML con tipo, esta propiedad es una cadena que especifica el nombre de la colección de esquemas XML que define el valor. |
Al igual que los valores de SSPROP_PARAM, todas estas propiedades son opcionales y su valor predeterminado es una cadena vacía. SSPROP_COL_XML_SCHEMACOLLECTION_CATALOGNAME y SSPROP_COL_XML_SCHEMACOLLECTION_SCHEMANAME solo pueden especificarse si se especifica SSPROP_COL_XML_SCHEMACOLLECTIONNAME. Al pasar XML al servidor, si se incluyen estos valores se comprueba su existencia (validez) en la base de datos actual y los datos de instancia se comprueban en el esquema. En todos los casos, para ser válidos, deben estar todos vacíos o todos rellenos.
Adiciones y cambios en las interfaces de OLE DB
OLE DB Driver for SQL Server agrega nuevos valores o cambios a muchas de las interfaces básicas de OLE DB.
La interfaz ISSCommandWithParameters
Para admitir el tipo de datos xml mediante OLE DB, el controlador OLE DB para SQL Server implementa diversos cambios, incluida la adición de la interfaz ISSCommandWithParameters. Esta nueva interfaz hereda de la interfaz OLE DB básica ICommandWithParameters. Además de los tres métodos heredados de ICommandWithParameters, GetParameterInfo, MapParameterNames y SetParameterInfo, ISSCommandWithParameters proporciona los métodos GetParameterProperties y SetParameterProperties, que se usan para administrar tipos de datos específicos del servidor.
Nota:
La interfaz ISSCommandWithParameters también usa la nueva estructura SSPARAMPROPS.
La interfaz IColumnsRowset
El controlador OLE DB para SQL Server agrega las siguientes columnas específicas de SQL Server al conjunto de filas devueltas por el método IColumnRowset::GetColumnsRowset. Estas columnas contienen el nombre de tres partes de una colección de esquemas XML. Para las columnas que no son XML o las columnas XML sin tipo, las tres columnas toman el valor predeterminado NULL.
Nombre de la columna | Tipo | Descripción |
---|---|---|
DBCOLUMN_SS_XML_SCHEMACOLLECTION_CATALOGNAME | DBTYPE_WSTR | Catálogo al que pertenece una colección de esquemas XML. De lo contrario, NULL. |
DBCOLUMN_SS_XML_SCHEMACOLLECTION_SCHEMANAME | DBTYPE_WSTR | Esquema al que pertenece una colección de esquemas XML. De lo contrario, NULL. |
DBCOLUMN_SS_XML_SCHEMACOLLECTIONNAME | DBTYPE_WSTR | Nombre de una colección de esquemas XML para columnas XML con tipo; de lo contrario, NULL. |
La interfaz IRowset
La instancia XML de una columna XML se recupera a través del método IRowset::GetData. Una instancia XML puede recuperarse como DBTYPE_BSTR, DBTYPE_WSTR, DBTYPE_VARIANT, DBTYPE_XML, DBTYPE_STR, DBTYPE_BYTES o como una interfaz a través de DBTYPE_IUNKNOWN, en función del enlace especificado por el cliente. Si el consumidor especifica DBTYPE_BSTR, DBTYPE_WSTR o DBTYPE_VARIANT, el proveedor convierte la instancia XML en el tipo solicitado por el usuario y la coloca en la ubicación especificada en el enlace correspondiente.
Si el consumidor especifica DBTYPE_IUNKNOWN y establece el argumento pObject en NULL o establece el argumento pObject en IID_ISequentialStream, el proveedor devuelve una interfaz ISequentialStream al consumidor para que este pueda transmitir los datos XML por secuencias fuera de la columna. Después, ISequentialStream devuelve los datos XML como una secuencia de caracteres Unicode.
Al devolver un valor XML enlazado a DBTYPE_IUNKNOWN, el proveedor notifica un valor de tamaño sizeof (IUnknown *)
. Este comportamiento es coherente con el enfoque que se aplica al enlazar una columna como DBTYPE_IUnknown o DBTYPE_IDISPATCH, y con el enfoque que aplica DBTYPE_IUNKNOWN/ISequentialStream cuando no puede determinarse el tamaño exacto de la columna.
La interfaz IRowsetChange
Un consumidor puede actualizar una instancia XML de una columna de dos formas. La primera, a través del objeto de almacenamiento ISequentialStream creado por el proveedor. El consumidor puede llamar al método ISequentialStream::Write para actualizar directamente la instancia XML devuelta por el proveedor.
La segunda, mediante los métodos IRowsetChange::SetData o IRowsetChange::InsertRow. En este enfoque, puede especificarse una instancia XML del búfer del consumidor en un enlace de tipo DBTYPE_BSTR, DBTYPE_WSTR, DBTYPE_VARIANT, DBTYPE_XML o DBTYPE_IUNKNOWN.
Si se especifica DBTYPE_BSTR, DBTYPE_WSTR o DBTYPE_VARIANT, el proveedor almacena la instancia XML que reside en el búfer del consumidor en la columna apropiada.
En el caso de DBTYPE_IUNKNOWN/ISequentialStream, si el consumidor no especifica ningún objeto de almacenamiento, el consumidor tiene que crear de antemano un objeto ISequentialStream, enlazar el documento XML con el objeto y, después, pasar el objeto al proveedor a través del método IRowsetChange::SetData. El consumidor también puede crear un objeto de almacenamiento, establecer el argumento pObject en IID_ISequentialStream, crear un objeto ISequentialStream y, después, pasar el objeto ISequentialStream al método IRowsetChange::SetData. En ambos casos, el proveedor puede recuperar el objeto XML a través del objeto ISequentialStream e insertarlo en una columna apropiada.
La interfaz IRowsetUpdate
La interfaz IRowsetUpdate proporciona funciones para las actualizaciones retrasadas. Los datos que están disponibles para los conjuntos de filas no están disponibles para otras transacciones hasta que el consumidor llama al método IRowsetUpdate::Update.
La interfaz IRowsetFind
El método IRowsetFind::FindNextRow no funciona con el tipo de datos xml. Cuando se llama a IRowsetFind::FindNextRow y el argumento hAccessor especifica una columna DBTYPE_XML, se devuelve DB_E_BADBINDINFO. Esto ocurre independientemente del tipo de columna que se esté buscando. En los demás tipos de enlaces, se produce un error en FindNextRow con DB_E_BADCOMPAREOP si el tipo de datos de la columna que va a buscarse es xml.
Consulte también
Controlador OLE DB para las características de SQL Server
ISSCommandWithParameters (OLE DB)