Cómo Insertar Registros de un Documento XML al Servidor SQL 2000 Utilizando el XML Bulk Load

Los registros de un documento XML pueden ser insertados fácilmente a una base de datos de MS SQL 2000 utilizando el objeto XML Bulk Load. El XML Bulk Load es parte del SQLXML Data Access Component y funciona de manera similar al BULK INSERT o la utilidad bcp. Es un objeto tipo COM que te permite insertar grandes cantidades de registros de modo rápido y eficiente.

Nota: Es preferible usar esta solución cuando el tamaño del documento XML es mayor de 5MB y se aplica al servidor SQL 2000 solamente. El servidor SQL 2005 tiene el XML Bulk Load incorporado y puedes ver ejemplos de cómo utilizarlo en la documentación del mismo.
Cabe destacar que el servidor SQL 2000 cuenta con la función OPENXML que facilita la manipulación de registros en un documento XML pero el uso de esta consume muchos recursos ya que el documento XML debe ser asignado a una variable. Más adelante veremos un ejemplo de cómo utilizar esta función.

Requerimientos
• SQLXML
• MS SQL 2000
• Conocimiento de XML
• El código fuente de este artículo

Empezamos por crear la tabla donde vamos a introducir los registros que aparecen en el documento XML. Este paso no es necesario como veremos más adelante en este artículo.

USE myBaseDeDatos;
GO
CREATE TABLE dbo.SalesOrderDetail (
SalesOrderID int NOT NULL ,
LineNumber tinyint NOT NULL ,
ProductID int NULL ,
SpecialOfferID int NULL ,
CarrierTrackingNumber nvarchar(25) NULL ,
OrderQty smallint NOT NULL ,
UnitPrice money NOT NULL ,
UnitPriceDiscount float NOT NULL,
ModifiedDate datetime NOT NULL,
rowguid uniqueidentifier NOT NULL,
LineTotal int NOT NULL);
GO

A seguir, crearemos el esquema XSD (click here)que describe el documento XML. En el primer elemento de este esquema podrás observar que hago referencia a la tabla “SalesOrderDetail”. Este elemento es utilizado para crear un vínculo entre el documento XML y la tabla donde se insertarán los registros si la tabla existe en la base de datos o en caso de que no exista, la tabla será creada con este nombre. Los elementos que siguen nombran las columnas de la tabla que existe o que se va a crear al igual que el tipo de data de las mismas.

Ya que tenemos el documento XML y el esquema XSD, procedemos a crear un pequeño programa en VBScript para ejecutar el único método del XML Bulk Load (Execute) el cual requiere de dos parámetros, el nombre del esquema (XSD) y el nombre del documento XML. Abre una sesión del Notepad y copia el texto que aparece en el Código3. Salva este archivo con el nombre BulkLoad.vbs en la misma carpeta donde tienes el documento XML y el XSD.

Option Explicit

Dim strMsg
Dim objBL
set objBL = CreateObject("SQLXMLBulkLoad.SQLXMLBulkload.3.0")
with objBL
.ConnectionString = "provider=SQLOLEDB;data source=localhost;database=dev;integrated security=SSPI"
.ErrorLogFile = "e:'error.log"
.SchemaGen = true
.Execute "Salesorderdetail.xsd", "Salesorderdetail.xml"
end with
set objBL=Nothing
strMsg = "Done!" & vbCrLf
msgbox(strMsg)

En el Código4 tenemos un procedimento almazenado que utiliza la función OPENXML y los procedimientos de systema sp_xml_preparedocument y sp_xml_removedocument para manipular un documento XML. Ahora, ya estamos listos para hacer nuestras pruebas y comparar el XML Bulk Load contra el OPENXML.

CREATE PROCEDURE dbo.prcINSERTSalesOrderDetail
       @strXML ntext

AS

SET NOCOUNT ON

DECLARE @iDoc int

EXEC @iDoc OUTPUT
   , @strXML

INSERT INTO dbo.SalesOrderDetail (
       SalesOrderID,
       LineNumber,
       ProductID,
       SpecialOfferID,
       CarrierTrackingNumber,
       OrderQty,
       UnitPrice,
       UnitPriceDiscount,
       ModifiedDate,
       rowguid,
       LineTotal)
(
SELECT *
  FROM OpenXML(@iDoc, '/table/row',2)
  WITH (SalesOrderID int,
        LineNumber tinyint,
        ProductID int,
        SpecialOfferID int,
        CarrierTrackingNumber nvarchar(25),
        OrderQty smallint,
        UnitPrice money,
        UnitPriceDiscount float,
        ModifiedDate varchar(30),
        rowguid varchar(60),
        LineTotal float)
)

EXEC sp_xml_removedocument @iDoc
GO

Ahora voy a describir los pasos que debes seguir para hacer las pruebas con el archivo ZIP que acompaña este artículo.
1. Descargar el archizo ZIP aqui.
2. Abrir una sesión del Analizador de consultas (Query Analyzer) y ejecutar el texto del archivo DataBaseObjects.sql
3. Ejecutar el 1_OPENXMLLoad.vbs. Inserta registros utilizando la función OPENXML.
4. Borrar todos los registros de la tabla SalesOrderDetail ejecutando el TRUNCATE TABLE SalesOrderDetail.
5. Ejecutar el 2_BulkLoad.vbs. Inserta registros utilizando el XML Bulk Upload.
6. Borrar todos los registros de la tabla SalesOrderDetail ejecutando el TRUNCATE TABLE SalesOrderDetail.
7. Ejecutar el 3_BulkLoad.vbs

En el paso 2, creamos la base de datos “dev”, la tabla “SalesOrderDetail” y el procedimiento almacenado “prcInsertCustomer”. En el paso 3 ejecutamos el 1_OPENXMLLoad.vbs el cual inserta los registros del documento salesorderdetail_OPENXML.xml a la tabla “SalesOrderDetail” la cual debe tener 67,599 registros. Después de remover los registros de la tabla “SalesOrderDetail” deben ejecutar el 2_BLoad.vbs el cual inserta los mismos 67,599 registros a la tabla “SalesOrd
erDetail” pero esta vez utilizando el XML Bulk Load. Es aquí donde podemos comparar la eficiencia y velocidad del XML Bulk Upload contra la función OPENXML. Además de ser más rápido, el XML Bulk Upload puede manejar documentos XML más grandes ya que estos no son cargados en la memoria. En el último paso, ejecutamos el 3_BulkLoad.vbs el cual inserta 121,371 registros de un documento XML de 60MB en menos tiempo y utilizando menos recursos de sistema que cuando ejecutamos el paso número tres.

Puedes descargar el código aquí, y no te olvides de añadir tus comentarios.

RECURSOS: SQLXML 3.0