Transformar salidas en batch con la utilidad sqlcmd a formato xml en SQL Server 2005.

Imagen de JuanPLG

Introducción:

Les voy a contar una solicitud que tuve en donde se me pedía renderizar o cambiar el formato de las salidas u output de los scripts de SQL Server 2005 mediante un formato tabulado como por ej: xls, csv, txt(campos separados por algún carácter en especial),etc.
A continuación les voy a dar una leve aproximación al entorno de trabajo y porque se realizaba esa solicitud.
Como les comente en notas anteriores, estoy trabajando en una migración de datos automática, en donde el proceso lee toda la info. de destino y genera sus propios scripts de migración con controles y creación de tablas dinámicas, con toda la meta data para migrar cualquier base de datos de usuarios, ustedes se preguntaran si lo realice a través un paquete de integration services en 2005, mi respuesta es NO, pues, como va a realizarse en 650 sites, por cuestiones de seguridad no permiten instalar las herramientas de debug en cada uno de los servidores afectados y si sucede algún problema es muy engorroso dar soporte, pues en cada sitio el lote de datos y objetos varia; por lo tanto tuve que realizarlo todo mediante script’s con TSQL y ejecución con controles vía templates mediante ‘sqlcmd’. En tanto y continuando con la descripción del entorno, pautas y tecnología utilizada, esta automatización también es encapsulada (como una gran cmd) por una aplicación de Microsoft denominada ‘Sequencer’, que ejecuta los script’s por base a migrar con los parámetros necesarios, por ej:

borratablas.cmd [mi_base_usuario]

El sequencer trabaja con los parámetros de salida de los script’s de migración, con lo cual recibe texto, pero para poder formatear y renderizar los datos del resultado de la migración de datos tabla por tabla, es muy engorroso que trabaje con los datos crudos para generar un reporte final.

Aclaración: La migración se realiza desde un ambiente Windows NT 4.0 – SQL Server 7.0 sp4 a Windows 2003 Server – SQL Server 2005 sp2.

Resolución del problema:

Como el Sequencer trabaja en forma nativa con XML y también el SQL Server 2005, procedimos a realizar una serie de pruebas para renderizar la salida u output de los script´s, las cuales se describen a continuación:

Prueba 1)

Objeto involucrado: Stored procedure “Reporte2”

CREATE PROCEDURE dbo.reporte2
AS
SET NOCOUNT ON
SELECT servidor,tabla,registros FROM resultado FOR XML AUTO

Comenzamos tratando de modificar el query para que devuelva el resultado en código XML, lo ejecuto por la ‘SQL Server Management Studio’ y el resultado del query es lo esperado, como figura a continuación:


Prueba 2)

Objeto involucrado: Stored procedure “Reporte2”

CREATE PROCEDURE dbo.reporte2
AS
SET NOCOUNT ON
SELECT servidor,tabla,registros FROM resultado FOR XML AUTO

Luego se ejecuta con la utilidad ‘sqlcmd’, la cual es la utilizada en todo el proceso de migración y encapsulada en el sequencer, pero el resultado no es el esperado.

Si chequeamos los ‘book´s on line’, nos da la opción de utilizar la función ‘:XML ON’, pero esta seteo o configuración de entorno no puede ser utilizada directamente de la forma:

sqlcmd –E –imiscript –omisalida –dmibase
O
sqlcmd –E –Q”exec mistoredprocedure” –omisalidastored -dmibase

Sino que debe realizarse como presenta la siguiente figura:

Por lo tanto este procedimiento no sirve para realizarlo en batch(sqlcmd –E –imiscript –omisalida –dmibase).

Prueba 3) Solución propiamente dicha.

Objeto involucrado: Stored procedure “Reporte”

CREATE PROCEDURE dbo.reporte
AS
SET NOCOUNT ON

DECLARE @xm xml
SET @xm=(SELECT top 20 servidor,tabla,registros FROM resultado FOR XML AUTO)

SELECT @xm

Se modifico el stored procedure creando una variable llamada @xm del tipo de dato xml, para que almacene el resultado del query y luego vía la utilidad ‘sqlcmd’ y ejecutando la misma en batch, la salida es finalmente renderizada en xml, con lo cual input-output entre la utilidad sqlcmd y el sequencer es nativo xml y sin problemas de tabulación y texto crudo, la siguiente figura presenta lo expuesto:

Por lo expuesto, este procedimiento sería el correcto para realizarlo en batch por ej: sqlcmd –E –imiscript –omisalida –dmibase -h-1(no presentan las líneas '---' o headers), pero, la utilidad sqlcmd posee una limitación (por llamarlo de alguna manera), la cual es que la salida no puede exceder de una cierta cantidad de caracteres o en otras palabras de 258 bytes. Con lo cual, si nos topamos con esta límitación, es recomendable realizar una conexion ADO a la base de datos afectada y obtener la totalidad de los registros tabulados, mediante la llamada al stored procedure que toma y convierte los datos de la base a XML.

Espero les sirva y un abrazo virtual para todos !