- Consolidamos la carga inicial de datos en un único script:
`SQL/Scripts/CargarDatosXML.sql`.
- Implementamos la carga usando `OPENXML` y
`sp_xml_preparedocument` para leer el XML en memoria y transformar sus nodos en
filas.
- Dejamos la carga como un procedimiento inicial ejecutable
una sola vez, con protección para evitar duplicados.
- Eliminamos los scripts parciales de carga por tabla para
que quede una sola fuente de verdad.
- Corregimos el cálculo de saldos: el procedimiento ahora
calcula `NuevoSaldo` y actualiza `Empleado.SaldoVacaciones` tomando el último
movimiento por empleado (no el MAX intermedio).
- La carga por scripts individuales fragmentaba la
inicialización y podía causar confusión; se resolvió unificando toda la carga
en `CargarDatosXML.sql`.
- La carga inicial generó inconsistencias de saldo debido a
dos causas que corregimos:
1. `TipoMovimiento.TipoAccion` en los datos
venía como `Credito`/`Debito`, pero la lógica interna esperaba códigos
(`'A'`/`'R'`), por lo que los CASEs devolvían 0. Solución: normalizar en la
carga.
2. El cálculo del saldo final usaba `MAX(m.NuevoSaldo)`
que devolvía valores intermedios en lugar del último saldo cronológico.
Solución: actualizar para tomar el último movimiento por fecha/PostTime/id.
- Se confirmó que el XML se usará solo como carga inicial y
no como fuente viva de cambios de la aplicación.
- Error de build TypeScript relacionado con
importación/casing en `src/utils/errorhelper.ts` que provocó un fallo de
compilación hasta corregir el path (error reportado por `tsc`).
- Resultado de ejecución de limpieza y reseed en
SSMS/`sqlcmd` (ejemplo de salida):
- `(16 rows affected)` / `(14 rows affected)`
... (salidas de DELETE/INSERT durante limpieza y carga)
- `Checking identity information: current
identity value '16'.` (salida de `DBCC CHECKIDENT`)
- Discrepancia inicial detectada al verificar saldos:
`SaldoCalculado` devolvía `0.00` para muchos empleados porque el CASE
comprobaba `TipoAccion = 'A'/'R'` pero la tabla contenía `Credito`/`Debito`.
USE VacacionesDB;
GO
IF OBJECT_ID('dbo.sp_CargarDatosInicialesXML', 'P') IS NOT NULL
DROP PROCEDURE dbo.sp_CargarDatosInicialesXML;
GO
CREATE PROCEDURE dbo.sp_CargarDatosInicialesXML
AS
BEGIN
SET NOCOUNT ON;
SET XACT_ABORT ON;
DECLARE @xml NVARCHAR(MAX) = N'
<Datos>
<Puestos>
<Puesto Nombre="Cajero" SalarioxHora="11.00"/>
<Puesto Nombre="Camarero" SalarioxHora="10.00"/>
<Puesto Nombre="Cuidador" SalarioxHora="13.50"/>
<Puesto Nombre="Conductor" SalarioxHora="15.00"/>
<Puesto Nombre="Asistente" SalarioxHora="11.00"/>
<Puesto Nombre="Recepcionista" SalarioxHora="12.00"/>
<Puesto Nombre="Fontanero" SalarioxHora="13.00"/>
<Puesto Nombre="Niñera" SalarioxHora="12.00"/>
<Puesto Nombre="Conserje" SalarioxHora="11.00"/>
<Puesto Nombre="Albañil" SalarioxHora="10.50"/>
</Puestos>
<TiposEvento>
<TipoEvento Id="1" Nombre="Login Exitoso"/>
<TipoEvento Id="2" Nombre="Login No Exitoso"/>
<TipoEvento Id="3" Nombre="Login deshabilitado"/>
<TipoEvento Id="4" Nombre="Logout"/>
<TipoEvento Id="5" Nombre="Insercion no exitosa"/>
<TipoEvento Id="6" Nombre="Insercion exitosa"/>
<TipoEvento Id="7" Nombre="Update no exitoso"/>
<TipoEvento Id="8" Nombre="Update exitoso"/>
<TipoEvento Id="9" Nombre="Intento de borrado"/>
<TipoEvento Id="10" Nombre="Borrado exitoso"/>
<TipoEvento Id="11" Nombre="Consulta con filtro de nombre"/>
<TipoEvento Id="12" Nombre="Consulta con filtro de cedula"/>
<TipoEvento Id="13" Nombre="Intento de insertar movimiento"/>
<TipoEvento Id="14" Nombre="Insertar movimiento exitoso"/>
</TiposEvento>
<TiposMovimientos>
<TipoMovimiento Id="1" Nombre="Cumplir mes" TipoAccion="Credito"/>
<TipoMovimiento Id="2" Nombre="Bono vacacional" TipoAccion="Credito"/>
<TipoMovimiento Id="3" Nombre="Reversion de Credito" TipoAccion="Credito"/>
<TipoMovimiento Id="4" Nombre="Disfrute de vacaciones" TipoAccion="Debito"/>
<TipoMovimiento Id="5" Nombre="Venta de vacaciones" TipoAccion="Debito"/>
<TipoMovimiento Id="6" Nombre="Reversion Debito" TipoAccion="Debito"/>
</TiposMovimientos>
<Empleados>
<empleado Puesto="Camarero" ValorDocumentoIdentidad="6993943" Nombre="Kaitlyn Jensen" FechaContratacion="2017-12-07"/>
<empleado Puesto="Albañil" ValorDocumentoIdentidad="1896802" Nombre="Robert Buchanan" FechaContratacion="2020-09-20"/>
<empleado Puesto="Cajero" ValorDocumentoIdentidad="5095109" Nombre="Christina Ward" FechaContratacion="2015-09-13"/>
<empleado Puesto="Fontanero" ValorDocumentoIdentidad="8403646" Nombre="Bradley Wright" FechaContratacion="2020-01-27"/>
<empleado Puesto="Conserje" ValorDocumentoIdentidad="6019592" Nombre="Robert Singh" FechaContratacion="2017-02-01"/>
<empleado Puesto="Asistente" ValorDocumentoIdentidad="4510358" Nombre="Ryan Mitchell" FechaContratacion="2018-06-08"/>
<empleado Puesto="Asistente" ValorDocumentoIdentidad="7517662" Nombre="Candace Fox" FechaContratacion="2013-12-17"/>
<empleado Puesto="Asistente" ValorDocumentoIdentidad="8326328" Nombre="Allison Murillo" FechaContratacion="2020-04-19"/>
<empleado Puesto="Cuidador" ValorDocumentoIdentidad="2161775" Nombre="Jessica Murphy" FechaContratacion="2017-04-12"/>
<empleado Puesto="Fontanero" ValorDocumentoIdentidad="2918773" Nombre="Nancy Newton PhD" FechaContratacion="2016-11-22"/>
<empleado Puesto="Conductor" ValorDocumentoIdentidad="9772211" Nombre="Alicia Ortega" FechaContratacion="2021-05-14"/>
<empleado Puesto="Recepcionista" ValorDocumentoIdentidad="6641189" Nombre="Pedro Salas" FechaContratacion="2019-03-21"/>
<empleado Puesto="Niñera" ValorDocumentoIdentidad="3389054" Nombre="Sofía Herrera" FechaContratacion="2022-08-09"/>
</Empleados>
<Usuarios>
<usuario Id="1" Nombre="UsuarioScripts" Pass="UsuarioScripts"/>
<usuario Id="2" Nombre="mgarrison" Pass=")*2LnSr^lk"/>
<usuario Id="3" Nombre="jgonzalez" Pass="3YSI0HtiXI"/>
<usuario Id="4" Nombre="zkelly" Pass="X4US4aLam@"/>
<usuario Id="5" Nombre="andersondeborah" Pass="732F34xo%S"/>
<usuario Id="6" Nombre="hardingmicheal" Pass="himB9Dzd%_"/>
<usuario Id="7" Nombre="martinezlisa" Pass="7Kp9vQ2mT1"/>
<usuario Id="8" Nombre="floresdaniel" Pass="H4s8Nq3xL6"/>
<usuario Id="9" Nombre="perezmaria" Pass="R2m7Bv5cZ8"/>
<usuario Id="10" Nombre="torresluis" Pass="J9t6Wk4pS3"/>
</Usuarios>
<Movimientos>
<movimiento ValorDocId="7517662" IdTipoMovimiento="Venta de vacaciones" Fecha="2024-01-18" Monto="2" PostByUser="hardingmicheal" PostInIP="42.142.119.153" PostTime="2024-01-18 18:47:14"/>
<movimiento ValorDocId="6993943" IdTipoMovimiento="Bono vacacional" Fecha="2024-10-31" Monto="1" PostByUser="mgarrison" PostInIP="156.92.82.57" PostTime="2024-10-31 12:43:18"/>
<movimiento ValorDocId="8326328" IdTipoMovimiento="Venta de vacaciones" Fecha="2024-11-22" Monto="7" PostByUser="andersondeborah" PostInIP="218.213.110.232" PostTime="2024-11-22 00:23:53"/>
<movimiento ValorDocId="4510358" IdTipoMovimiento="Reversion de Credito" Fecha="2024-07-03" Monto="3" PostByUser="hardingmicheal" PostInIP="143.42.131.166" PostTime="2024-07-03 17:07:39"/>
<movimiento ValorDocId="8403646" IdTipoMovimiento="Reversion de Credito" Fecha="2024-12-07" Monto="8" PostByUser="zkelly" PostInIP="155.44.100.105" PostTime="2024-12-07 15:44:30"/>
<movimiento ValorDocId="8326328" IdTipoMovimiento="Venta de vacaciones" Fecha="2024-11-26" Monto="10" PostByUser="hardingmicheal" PostInIP="141.163.255.56" PostTime="2024-11-26 09:33:41"/>
<movimiento ValorDocId="6993943" IdTipoMovimiento="Disfrute de vacaciones" Fecha="2024-11-20" Monto="6" PostByUser="hardingmicheal" PostInIP="4.176.52.1" PostTime="2024-11-20 23:31:41"/>
<movimiento ValorDocId="2918773" IdTipoMovimiento="Disfrute de vacaciones" Fecha="2024-10-30" Monto="10" PostByUser="zkelly" PostInIP="220.164.108.231" PostTime="2024-10-30 03:55:57"/>
<movimiento ValorDocId="2161775" IdTipoMovimiento="Reversion Debito" Fecha="2024-06-13" Monto="2" PostByUser="hardingmicheal" PostInIP="135.223.57.22" PostTime="2024-06-13 13:28:39"/>
<movimiento ValorDocId="8403646" IdTipoMovimiento="Bono vacacional" Fecha="2024-01-01" Monto="6" PostByUser="zkelly" PostInIP="150.250.94.62" PostTime="2024-01-01 05:17:10"/>
<movimiento ValorDocId="2918773" IdTipoMovimiento="Venta de vacaciones" Fecha="2024-07-12" Monto="6" PostByUser="hardingmicheal" PostInIP="218.191.123.15" PostTime="2024-07-12 09:10:16"/>
<movimiento ValorDocId="5095109" IdTipoMovimiento="Reversion de Credito" Fecha="2024-12-27" Monto="14" PostByUser="hardingmicheal" PostInIP="136.103.23.170" PostTime="2024-12-27 12:59:03"/>
<movimiento ValorDocId="6993943" IdTipoMovimiento="Venta de vacaciones" Fecha="2024-04-08" Monto="1" PostByUser="jgonzalez" PostInIP="158.48.100.86" PostTime="2024-04-08 01:24:38"/>
<movimiento ValorDocId="8403646" IdTipoMovimiento="Bono vacacional" Fecha="2024-08-25" Monto="8" PostByUser="jgonzalez" PostInIP="204.0.219.231" PostTime="2024-08-25 16:24:07"/>
<movimiento ValorDocId="5095109" IdTipoMovimiento="Bono vacacional" Fecha="2024-03-07" Monto="7" PostByUser="andersondeborah" PostInIP="208.0.4.33" PostTime="2024-03-07 08:19:28"/>
<movimiento ValorDocId="9772211" IdTipoMovimiento="Cumplir mes" Fecha="2024-02-14" Monto="4" PostByUser="martinezlisa" PostInIP="10.10.10.10" PostTime="2024-02-14 08:11:00"/>
<movimiento ValorDocId="6641189" IdTipoMovimiento="Bono vacacional" Fecha="2024-02-28" Monto="3" PostByUser="floresdaniel" PostInIP="10.10.10.11" PostTime="2024-02-28 09:20:15"/>
<movimiento ValorDocId="3389054" IdTipoMovimiento="Disfrute de vacaciones" Fecha="2024-03-12" Monto="5" PostByUser="perezmaria" PostInIP="10.10.10.12" PostTime="2024-03-12 14:05:45"/>
<movimiento ValorDocId="9772211" IdTipoMovimiento="Reversion de Credito" Fecha="2024-04-03" Monto="2" PostByUser="torresluis" PostInIP="10.10.10.13" PostTime="2024-04-03 11:30:05"/>
<movimiento ValorDocId="6641189" IdTipoMovimiento="Venta de vacaciones" Fecha="2024-04-19" Monto="1" PostByUser="mgarrison" PostInIP="172.16.0.21" PostTime="2024-04-19 16:42:31"/>
<movimiento ValorDocId="3389054" IdTipoMovimiento="Reversion Debito" Fecha="2024-05-02" Monto="3" PostByUser="jgonzalez" PostInIP="172.16.0.22" PostTime="2024-05-02 07:18:09"/>
<movimiento ValorDocId="5095109" IdTipoMovimiento="Cumplir mes" Fecha="2024-05-18" Monto="6" PostByUser="andersondeborah" PostInIP="172.16.0.23" PostTime="2024-05-18 18:22:40"/>
<movimiento ValorDocId="4510358" IdTipoMovimiento="Disfrute de vacaciones" Fecha="2024-06-09" Monto="4" PostByUser="hardingmicheal" PostInIP="172.16.0.24" PostTime="2024-06-09 12:10:55"/>
<movimiento ValorDocId="6019592" IdTipoMovimiento="Bono vacacional" Fecha="2024-06-25" Monto="2" PostByUser="martinezlisa" PostInIP="172.16.0.25" PostTime="2024-06-25 09:44:03"/>
<movimiento ValorDocId="7517662" IdTipoMovimiento="Reversion de Credito" Fecha="2024-07-11" Monto="5" PostByUser="floresdaniel" PostInIP="172.16.0.26" PostTime="2024-07-11 13:55:27"/>
<movimiento ValorDocId="8403646" IdTipoMovimiento="Venta de vacaciones" Fecha="2024-08-08" Monto="4" PostByUser="perezmaria" PostInIP="172.16.0.27" PostTime="2024-08-08 15:00:00"/>
<movimiento ValorDocId="6993943" IdTipoMovimiento="Cumplir mes" Fecha="2024-09-14" Monto="7" PostByUser="torresluis" PostInIP="172.16.0.28" PostTime="2024-09-14 10:25:18"/>
<movimiento ValorDocId="2161775" IdTipoMovimiento="Reversion Debito" Fecha="2024-10-05" Monto="1" PostByUser="zkelly" PostInIP="172.16.0.29" PostTime="2024-10-05 08:12:49"/>
<movimiento ValorDocId="2918773" IdTipoMovimiento="Bono vacacional" Fecha="2024-11-03" Monto="2" PostByUser="martinezlisa" PostInIP="172.16.0.30" PostTime="2024-11-03 17:33:12"/>
<movimiento ValorDocId="8326328" IdTipoMovimiento="Venta de vacaciones" Fecha="2024-12-18" Monto="8" PostByUser="floresdaniel" PostInIP="172.16.0.31" PostTime="2024-12-18 19:47:59"/>
</Movimientos>
<Error>
<error Codigo="50001" Descripcion="Username no existe"/>
<error Codigo="50002" Descripcion="Password no existe"/>
<error Codigo="50003" Descripcion="Login deshabilitado"/>
<error Codigo="50004" Descripcion="Empleado con ValorDocumentoIdentidad ya existe en inserción"/>
<error Codigo="50005" Descripcion="Empleado con mismo nombre ya existe en inserción"/>
<error Codigo="50006" Descripcion="Empleado con ValorDocumentoIdentidad ya existe en actualizacion"/>
<error Codigo="50007" Descripcion="Empleado con mismo nombre ya existe en actualización"/>
<error Codigo="50008" Descripcion="Error de base de datos"/>
<error Codigo="50009" Descripcion="Nombre de empleado no alfabético"/>
<error Codigo="50010" Descripcion="Valor de documento de identidad no alfabético"/>
<error Codigo="50011" Descripcion="Monto del movimiento rechazado pues si se aplicar el saldo seria negativo."/>
</Error>
</Datos>';
DECLARE @handle INT = NULL;
BEGIN TRY
EXEC sp_xml_preparedocument @handle OUTPUT, @xml;
BEGIN TRANSACTION;
-- Puestos: se cargan por nombre porque el resto de la app los usa como catálogo.
INSERT INTO dbo.Puesto (Nombre, SalarioxHora)
SELECT x.Nombre, x.SalarioxHora
FROM OPENXML(@handle, '/Datos/Puestos/Puesto', 1)
WITH (
Nombre NVARCHAR(128) '@Nombre',
SalarioxHora DECIMAL(10,2) '@SalarioxHora'
) AS x
WHERE NOT EXISTS (
SELECT 1
FROM dbo.Puesto p
WHERE p.Nombre = x.Nombre
);
-- Tipos de evento: el Id del XML no se conserva literal, pero el catálogo sí queda completo.
INSERT INTO dbo.TipoEvento (Nombre)
SELECT x.Nombre
FROM OPENXML(@handle, '/Datos/TiposEvento/TipoEvento', 1)
WITH (
Id INT '@Id',
Nombre NVARCHAR(128) '@Nombre'
) AS x
WHERE NOT EXISTS (
SELECT 1
FROM dbo.TipoEvento t
WHERE t.Nombre = x.Nombre
);
-- Tipos de movimiento: se cargan por nombre y tipo de acción normalizada.
INSERT INTO dbo.TipoMovimiento (Nombre, TipoAccion)
SELECT
x.Nombre,
CASE
WHEN x.TipoAccion = 'Credito' THEN 'A'
WHEN x.TipoAccion = 'Debito' THEN 'R'
ELSE x.TipoAccion
END AS TipoAccion
FROM OPENXML(@handle, '/Datos/TiposMovimientos/TipoMovimiento', 1)
WITH (
Id INT '@Id',
Nombre NVARCHAR(128) '@Nombre',
TipoAccion NVARCHAR(32) '@TipoAccion'
) AS x
WHERE NOT EXISTS (
SELECT 1
FROM dbo.TipoMovimiento t
WHERE t.Nombre = x.Nombre
);
-- Usuarios: se cargan por username y password.
INSERT INTO dbo.Usuario (Username, Password)
SELECT x.Nombre, x.Pass
FROM OPENXML(@handle, '/Datos/Usuarios/usuario', 1)
WITH (
Id INT '@Id',
Nombre NVARCHAR(128) '@Nombre',
Pass NVARCHAR(128) '@Pass'
) AS x
WHERE NOT EXISTS (
SELECT 1
FROM dbo.Usuario u
WHERE u.Username = x.Nombre
);
-- Códigos de error: el catálogo queda disponible para traducir mensajes en el backend.
INSERT INTO dbo.Error (Codigo, Descripcion)
SELECT x.Codigo, x.Descripcion
FROM OPENXML(@handle, '/Datos/Error/error', 1)
WITH (
Codigo INT '@Codigo',
Descripcion NVARCHAR(256) '@Descripcion'
) AS x
WHERE NOT EXISTS (
SELECT 1
FROM dbo.Error e
WHERE e.Codigo = x.Codigo
);
-- Empleados: se enlazan al puesto cargado arriba por el nombre del puesto.
INSERT INTO dbo.Empleado (idPuesto, ValorDocumentoIdentidad, Nombre, FechaContratación, SaldoVacaciones, EsActivo)
SELECT p.id, x.ValorDocumentoIdentidad, x.Nombre, x.FechaContratacion, 0.00, 1
FROM OPENXML(@handle, '/Datos/Empleados/empleado', 1)
WITH (
Puesto NVARCHAR(128) '@Puesto',
ValorDocumentoIdentidad NVARCHAR(32) '@ValorDocumentoIdentidad',
Nombre NVARCHAR(128) '@Nombre',
FechaContratacion DATE '@FechaContratacion'
) AS x
INNER JOIN dbo.Puesto p
ON p.Nombre = x.Puesto
WHERE NOT EXISTS (
SELECT 1
FROM dbo.Empleado e
WHERE e.ValorDocumentoIdentidad = x.ValorDocumentoIdentidad
);
-- Movimientos: primero se extraen a una tabla temporal para poder calcular el saldo acumulado.
CREATE TABLE #MovimientosXml (
ValorDocumentoIdentidad NVARCHAR(32) NOT NULL,
NombreTipoMovimiento NVARCHAR(128) NOT NULL,
Fecha DATE NOT NULL,
Monto DECIMAL(10,2) NOT NULL,
PostByUser NVARCHAR(128) NOT NULL,
PostInIP NVARCHAR(32) NOT NULL,
PostTime DATETIME NOT NULL
);
INSERT INTO #MovimientosXml (
ValorDocumentoIdentidad,
NombreTipoMovimiento,
Fecha,
Monto,
PostByUser,
PostInIP,
PostTime
)
SELECT
x.ValorDocumentoIdentidad,
x.NombreTipoMovimiento,
x.Fecha,
x.Monto,
x.PostByUser,
x.PostInIP,
x.PostTime
FROM OPENXML(@handle, '/Datos/Movimientos/movimiento', 1)
WITH (
ValorDocumentoIdentidad NVARCHAR(32) '@ValorDocId',
NombreTipoMovimiento NVARCHAR(128) '@IdTipoMovimiento',
Fecha DATE '@Fecha',
Monto DECIMAL(10,2) '@Monto',
PostByUser NVARCHAR(128) '@PostByUser',
PostInIP NVARCHAR(32) '@PostInIP',
PostTime DATETIME '@PostTime'
) AS x;
;WITH MovimientosConSaldo AS (
SELECT
e.id AS idEmpleado,
tm.id AS idTipoMovimiento,
m.Fecha,
m.Monto,
CASE
WHEN tm.TipoAccion = 'A' THEN m.Monto
ELSE -m.Monto
END AS MovimientoFirmado,
SUM(
CASE
WHEN tm.TipoAccion = 'A' THEN m.Monto
ELSE -m.Monto
END
) OVER (
PARTITION BY e.id
ORDER BY m.Fecha, m.PostTime, tm.id, m.Monto
ROWS UNBOUNDED PRECEDING
) AS NuevoSaldo,
u.id AS idUsuario,
m.PostInIP,
m.PostTime
FROM #MovimientosXml m
INNER JOIN dbo.Empleado e
ON e.ValorDocumentoIdentidad = m.ValorDocumentoIdentidad
INNER JOIN dbo.TipoMovimiento tm
ON tm.Nombre = m.NombreTipoMovimiento
INNER JOIN dbo.Usuario u
ON u.Username = m.PostByUser
)
INSERT INTO dbo.Movimiento (idEmpleado, idTipoMovimiento, Fecha, Monto, NuevoSaldo, idUsuario, IpPostIn, PostTime)
SELECT
s.idEmpleado,
s.idTipoMovimiento,
s.Fecha,
s.Monto,
s.NuevoSaldo,
s.idUsuario,
s.PostInIP,
s.PostTime
FROM MovimientosConSaldo s
WHERE NOT EXISTS (
SELECT 1
FROM dbo.Movimiento m
WHERE m.idEmpleado = s.idEmpleado
AND m.idTipoMovimiento = s.idTipoMovimiento
AND m.Fecha = s.Fecha
AND m.Monto = s.Monto
AND m.idUsuario = s.idUsuario
AND m.IpPostIn = s.PostInIP
AND m.PostTime = s.PostTime
);
-- El saldo actual del empleado debe reflejar el último movimiento cargado.
;WITH UltimoMovimiento AS (
SELECT
m.idEmpleado,
m.NuevoSaldo,
ROW_NUMBER() OVER (
PARTITION BY m.idEmpleado
ORDER BY m.Fecha DESC, m.PostTime DESC, m.id DESC
) AS rn
FROM dbo.Movimiento m
),
SaldoFinal AS (
SELECT
idEmpleado,
NuevoSaldo
FROM UltimoMovimiento
WHERE rn = 1
)
UPDATE e
SET e.SaldoVacaciones = ISNULL(s.NuevoSaldo, 0.00)
FROM dbo.Empleado e
LEFT JOIN SaldoFinal s
ON s.idEmpleado = e.id;
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0
ROLLBACK TRANSACTION;
IF @handle IS NOT NULL
EXEC sp_xml_removedocument @handle;
THROW;
END CATCH;
IF @handle IS NOT NULL
EXEC sp_xml_removedocument @handle;
END;
GO
EXEC dbo.sp_CargarDatosInicialesXML;
GO
- Cuando una carga es inicial y estática, conviene tener un
único punto de entrada en vez de varios scripts dispersos.
- `OPENXML` sirve bien cuando el XML se quiere tratar como
documento en memoria y convertirlo en filas SQL.
- Mantener solo una fuente de verdad evita inconsistencias
entre scripts que hacen la misma tarea.
- Validar todo, buscar errores, ver si falla algo, terminar el analisis de resultados, y basicamente, cerrar lo que queda
Comentarios
Publicar un comentario