Miércoles 10 de Junio
Inicio: 11:30 a.m
Fin: 3:20 p.m
11:30 a.m - 11:45 a.m
Analicé el archivo XML, visualicé que tenía varios caracteres que el SQL no soportaba, pensé mis opciones para cambiar todos los posibles errores que incluían las vocales con tildes, vocales con diéresis y otros caracteres extraños del inglés.
Tenía que utilizar herramientas para reemplazar los errores que me daban pues el XML posee más de 45680 líneas y obviamente no lo podía hacer manualmente. Notepad++ no lo podía utilizar ya que este programa sustituía los caracteres extraños por números hexadecimales, así que decidí utilizar el reeplace all del notepad de Windows.
11:45 a.m - 12:45 p.m
Junto con el SQL, notepad++ y notepad de Windows rastrié los caracteres, el SQL me decía la línea del caracter del error, en el notepad++ buscaba la línea para saber cuál era el caracter del error, el cual reemplazaba todas las posibles apariciones en el XML por medio del noteped de Windows. Este procedimiento fue muy lento y tedioso por la cantidad de caracteres diferentes que se agregaron en el XML.
12:45 p.m - 1:50 p.m
Ya cuando el XML estaba listo, me dediqué a buscar información de cómo leer XML e insertarlo en las tablas temporales para posteriormente procesar la información y insertarlos en la base de datos.
Para mi sorpresa, el XML de los compañeros era un poco diferente de los XML usuales, aquí un ejemplo de las pequeñas diferencias que afectan mucho el código.
XML de los compañeros:
<?xml version="1.0" encoding="UTF-8"?>
<company>
<period startDate="07/12/2014" endDate="08/06/2015">
<farm name="Santander" code="25282" >
<lot name="Cisneros" code="23986" cropType="Frijol">
<activity description="Reciclaje de residuos organicos">
<machinery name="Maquinaria 0" requestFrom="Baldomero Ayllon" manager="Albino Garay" requestDate="10/02/2014" transactionDate="10/02/2014" units="6" status="Approved" costPerHour="4542" duration="2" note="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."></machinery>
XML de tutoriales:
<?xml version="1.0"?>
<File>
<Row>
<Operation>NormalHour</Operation>
<Data>1/2014-08-20/12</Data>
</Row>
<Row>
<Operation>NormalHour</Operation>
<Data>2/2014-08-20/10</Data>
</Row>
<Row>
<Operation>NormalHour</Operation>
<Data>3/2014-08-20/8</Data>
</Row>
Como podemos ver, en la primera versión la información está dentro de los signos de <>, diferenciado de nombres significativos con la información entre comillas. En la segunda versión los nombres significativos están en medio de los signos <>, seguidos por la información de una en una.
Así que tenía que tener esto en cuenta al escribir el código.
El primer SP fue el más difícil, pero después de hacer que funcionara los demás eran copiar y pegar, cambiarle algunos elementos y listo.
El primer SP me quedó así.
DECLARE @periodoVar TABLE(Id INT NOT NULL IDENTITY(1,1),
fechaInicio date, fechafin date)
INSERT INTO @periodoVar
SELECT
usr.value('@startDate', 'date') as fechaInicio,
usr.value('@endDate','date') as fechafin
FROM @fincaInfo.nodes('/company/period') as a(usr)
select * from @periodoVar
1:50 p.m - 2:00 p.m
Cambié los parametros que leo en el XML de la primera función.
/*--------------------------------------------------------------
Leo la finca
---------------------------------------------------------------*/
DECLARE @fincaVar TABLE(Id INT NOT NULL IDENTITY(1,1),
nombre Varchar(50))
INSERT INTO @fincaVar
SELECT
usr.value('@name', 'Varchar(50)') as nombre
FROM @fincaInfo.nodes('/company/period/farm') as a(usr)
select * from @fincaVar
2:00 p.m - 2:10 p.m
Cambié los parametros que leo en el XML de la primera función.
/*--------------------------------------------------------------
Leo la el código del lote y su tipo de cosecha
---------------------------------------------------------------*/
DECLARE @loteVar TABLE(Id INT NOT NULL IDENTITY(1,1),
codigo int, tipoCosecha Varchar(50))
INSERT INTO @loteVar
SELECT
usr.value('@code', 'Varchar(50)') as codigo,
usr.value('@cropType', 'Varchar(50)') as tipoCosecha
FROM @fincaInfo.nodes('/company/period/farm/lot') as a(usr)
select * from @loteVar
2:10 p.m - 2:20 p.m
Cambié los parametros que leo en el XML de la primera función.
/*--------------------------------------------------------------
Leo la actividad
---------------------------------------------------------------*/
DECLARE @actividadVar TABLE(Id INT NOT NULL IDENTITY(1,1),
descripcion Varchar(50))
INSERT INTO @actividadVar
SELECT
usr.value('@description', 'Varchar(50)') as descripcion
FROM @fincaInfo.nodes('/company/period/farm/lot/activity') as a(usr)
select * from @actividadVar
2:20 p.m - 2:40 p.m
Cambié los parametros que leo en el XML de la primera función.
Esta función fue un poco más difícil ya que era más larga y compleja, había que agregarle más parámetros
/*--------------------------------------------------------------
Leo la maquinaria, el solicitante, el manager, la fecha de solicitud,
fecha de transacción, unidades, duración, costo por hora y el estado
---------------------------------------------------------------*/
DECLARE @infoSolucitudVar TABLE(Id INT NOT NULL IDENTITY(1,1),
nombreMaquina Varchar(50), nombreSolicitante Varchar(50),
nombreManager Varchar(50), fechaSolucitud date, fechaTransaccion date,
unidades int, duracion int, costoxHora int, estado Varchar(50))
INSERT INTO @infoSolucitudVar
SELECT
usr.value('@name', 'Varchar(50)') as nombreMaquina,
usr.value('@requestFrom', 'Varchar(50)') as nombreSolicitante,
usr.value('@manager', 'Varchar(50)') as nombreManager,
usr.value('@requestDate', 'date') as fechaSolucitud,
usr.value('@transactionDate', 'date') as fechaTransaccion,
usr.value('@units', 'int') as unidades,
usr.value('@duration', 'int') as duracion,
usr.value('@costPerHour', 'int') as costoxHora,
usr.value('@status', 'Varchar(50)') as estado
FROM @fincaInfo.nodes('/company/period/farm/lot/activity/machinery') as a(usr)
select * from @infoSolucitudVar
2:40 p.m - 3:00 p.m
Cambié los parametros que leo en el XML de la primera función.
Esta función fue un poco más difícil ya que era más larga y compleja, había que agregarle más parámetros
/*--------------------------------------------------------------
Leo el suministro, el solicitante, el manager, la fecha de solicitud,
fecha de transacción, nota de la transacción, unidades, tipo de unidad,
duración, costo por unidad y el estado
---------------------------------------------------------------*/
DECLARE @infoSuministroVar TABLE(Id INT NOT NULL IDENTITY(1,1),
nombreSuministro Varchar(50), nombreSolicitante Varchar(50),
nombreManager Varchar(50), fechaSolucitud date, fechaTransaccion date,
notaTransaccion varchar(50), unidades int, tipoUnidad varchar(50),
costoxUnidad int, estado Varchar(50))
INSERT INTO @infoSuministroVar
SELECT
usr.value('@name', 'Varchar(50)') as nombreSuministro,
usr.value('@requestFrom', 'Varchar(50)') as nombreSolicitante,
usr.value('@manager', 'Varchar(50)') as nombreManager,
usr.value('@requestDate', 'date') as fechaSolucitud,
usr.value('@transactionDate', 'date') as fechaTransaccion,
usr.value('@transactionNote', 'Varchar(50)') as notaTransaccion,
usr.value('@units', 'int') as unidades,
usr.value('@unitType', 'Varchar(50)') as tipoUnidad,
usr.value('@costPerUnit', 'int') as costoxUnidad,
usr.value('@status', 'Varchar(50)') as estado
FROM @fincaInfo.nodes('/company/period/farm/lot/activity/supply') as a(usr)
select * from @infoSuministroVar
3:00 p.m - 3:20 p.m
Cambié los parametros que leo en el XML de la primera función.
Esta función fue un poco más difícil ya que era más larga y compleja, había que agregarle más parámetros
/*--------------------------------------------------------------
Leo el servicio, el solicitante, el manager, la fecha de solicitud,
fecha de transacción, número de personas, duración, costo por hora
y el estado
---------------------------------------------------------------*/
DECLARE @infoServicioVar TABLE(Id INT NOT NULL IDENTITY(1,1),
nombreServicio Varchar(50), nombreSolicitante Varchar(50),
nombreManager Varchar(50), fechaSolucitud date, fechaTransaccion date,
personas int, duracion int,
costoxHora int, estado Varchar(50))
INSERT INTO @infoServicioVar
SELECT
usr.value('@name', 'Varchar(50)') as nombreServicio,
usr.value('@requestFrom', 'Varchar(50)') as nombreSolicitante,
usr.value('@manager', 'Varchar(50)') as nombreManager,
usr.value('@requestDate', 'date') as fechaSolucitud,
usr.value('@transactionDate', 'date') as fechaTransaccion,
usr.value('@persons', 'int') as personas,
usr.value('@duration', 'int') as duracion,
usr.value('@costPerHour', 'int') as costoxHora,
usr.value('@status', 'Varchar(50)') as estado
FROM @fincaInfo.nodes('/company/period/farm/lot/activity/service') as a(usr)
select * from @infoServicioVar
3:00 p.m - 3:20 p.m
Por último agregué la seguridad contra detección de errores, algo somple pero funciona, :)
END TRY
BEGIN CATCH
PRINT ERROR_NUMBER()
PRINT ERROR_SEVERITY()
PRINT ERROR_STATE()
PRINT ERROR_PROCEDURE()
PRINT ERROR_LINE()
PRINT ERROR_MESSAGE()
END CATCH
Bibliografía
Leer el XML:
http://stackoverflow.com/questions/4815836/how-do-you-read-xml-column-in-sql-server-2008
Control de errores:
http://www.devjoker.com/contenidos/articulos/255/Control-de-errores-en-Transact-SQL.aspx