Cambios sugeridos por el profesor en la Progra 2
Natalia Vargas Reyes (2 horas) de 8:00 pm a 10:00 pm
Cambios como usar joins en lugar de tantos select, utilizar bien los campos de cantidad de retiros automáticos o humanos en lugar de hacer counts que ralentizaban el proceso.
La nueva versión, con todos los insert y llamadas a funciones y otros SP, en una tercra versión quedó de la siguiente manera:
Nota: Solo son algunas mejoras, aún no se ha iniciado con lo que respecta a las Cuentas Objetivo
------------------------------Persona-----------------------------------------
INSERT INTO [dbo].[Persona]
(
[IdTipoDocumentoIdentidad]
,[Nombre]
,[ValorDocumentoIdentidad]
,[FechaNacimiento]
,[CorreoElectronico]
,[Telefono1]
,[Telefono2]
,[InsertAt]
,[UpdateAt]
,[InsertBy]
,[UpdateBy]
,[InsertIn]
,[UpdateIn]
)
SELECT
d.value('@TipoDocuIdentidad', 'INT')
, d.value('@Nombre', 'VARCHAR(100)')
, d.value('@ValorDocumentoIdentidad', 'VARCHAR(50)')
, d.value('@FechaNacimiento', 'DATETIME')
, d.value('@Email', 'VARCHAR(50)')
, d.value('@Telefono1', 'VARCHAR(50)')
, d.value('@Telefono2', 'VARCHAR(50)')
, @FechaOperacion AS [InsertAt] --obtiene la fecha del dia de insercion
, GETDATE() AS [UpdateAt] --obtiene la fecha del dia de actualizacion
, CURRENT_USER AS [InsertBy] --string de prueba
, CURRENT_USER AS [UpdateBy] --string de prueba
, 'Azure-server' AS [InsertIn] --string de prueba
, 'Azure-server' AS [UpdateIn] --string de prueba
FROM
@DocumentoXML.nodes('Operaciones/FechaOperacion[sql:variable("@punteroFecha")]/Persona') AS t(d);
----------------------------------CuentaAhorro-----------------------------------
--contar la cantidad de cuentas ahorro
SELECT @LenCuenta = COUNT(O.f.value('@ValorDocumentoIdentidadDelCliente','INT'))--probar ahí si no probar con numeros de cuenta
FROM @DocumentoXML.nodes('Operaciones/FechaOperacion[sql:variable("@punteroFecha")]/Cuenta') AS O(f)
SET @IteradorCuenta=1
WHILE @IteradorCuenta<=@LenCuenta--para ir iterando sobre cada cuenta en cada nodo fecha
BEGIN
INSERT INTO [dbo].[CuentaAhorro]
(
[IdPersona]
,[IdTipoCuenta]
,[NumeroDeCuenta]
,[FechaCreacion]
,[Saldo]
,[InsertAt]
,[UpdateAt]
,[InsertBy]
,[UpdateBy]
,[InsertIn]
,[UpdateIn]
)
SELECT
P.Id
, C.value('@TipoCuentaId', 'INT')
, C.value('@NumeroCuenta', 'INT')
, @FechaOperacion --Fecha de creacion
, 0 --Saldo inicial
, @FechaOperacion AS [InsertAt]
, GETDATE() AS [UpdateAt] --obtiene la fecha del dia de actualizacion
, CURRENT_USER AS [InsertBy]
, CURRENT_USER AS [UpdateBy] --Usuario actual de la BD
, 'Azure-server' AS [InsertIn]
, 'Azure-server' AS [UpdateIn]
FROM
@DocumentoXML.nodes('Operaciones/FechaOperacion[sql:variable("@punteroFecha")]/Cuenta[sql:variable("@IteradorCuenta")]') AS S(C)
INNER JOIN [dbo].[Persona] AS P ON C.value('@ValorDocumentoIdentidadDelCliente', 'INT') = P.ValorDocumentoIdentidad
SET @IteradorCuenta = @IteradorCuenta+1
END
-------------------------Beneficiario------------------------------------------------
INSERT INTO [dbo].[Beneficiario]
(
[IdPersona]
,[IdCuentaDeAhorro]
,[IdTipoParentezco]
,[Porcentaje]
,[Activo]
,[InsertAt]
,[UpdateAt]
,[InsertBy]
,[UpdateBy]
,[InsertIn]
,[UpdateIn]
)
SELECT
P.Id
,CA.Id
, d.value('@ParentezcoId', 'INT')
, d.value('@Porcentaje', 'INT')
, 1 AS [Activo]
, GETDATE() AS [InsertAt] --obtiene la fecha del dia de insercion
, GETDATE() AS [UpdateAt] --obtiene la fecha del dia de actualizacion
, CURRENT_USER AS [InsertBy] --string de prueba
, CURRENT_USER AS [UpdateBy] --string de prueba
, 'Azure-server' AS [InsertIn] --string de prueba
, 'Azure-server' AS [UpdateIn] --string de prueba
FROM
@DocumentoXML.nodes('Operaciones/FechaOperacion[sql:variable("@punteroFecha")]/Beneficiario') AS t(d)
INNER JOIN [dbo].[CuentaAhorro] AS CA ON d.value('@NumeroCuenta', 'INT') = CA.NumeroDeCuenta
INNER JOIN [dbo].[Persona] AS P ON d.value('@ValorDocumentoIdentidadBeneficiario', 'INT') = P.ValorDocumentoIdentidad
-------------------------------- Usuarios --------------------------------
INSERT INTO [dbo].[Usuario]
(
[Nombre]
,[Password]
,[EsAdministrador]
,[InsertAt]
,[UpdateAt]
,[InsertBy]
,[UpdateBy]
,[InsertIn]
,[UpdateIn]
)
SELECT
d.value('@User', 'VARCHAR(100)')
, d.value('@Pass', 'VARCHAR(100)')
, d.value('@EsAdministrador', 'BIT')
, GETDATE() AS [InsertAt] --obtiene la fecha del dia de insercion
, GETDATE() AS [UpdateAt] --obtiene la fecha del dia de actualizacion
, 'DB Admin' AS [InsertBy] --string de prueba
, 'DB Admin' AS [UpdateBy] --string de prueba
, 'Costa Rica' AS [InsertIn] --string de prueba
, 'Costa Rica' AS [UpdateIn] --string de prueba
FROM
@DocumentoXML.nodes('Operaciones/FechaOperacion[sql:variable("@punteroFecha")]/Usuario') AS t(d);
-------------------------------- usuariosPuedeVER --------------------------------
INSERT INTO [dbo].[UsuarioPuedeAccesar]
(
[IdUsuario]
,[IdCuentaDeAhorros]
,[Activo]
,[InsertAt]
,[UpdateAt]
,[InsertBy]
,[UpdateBy]
,[InsertIn]
,[UpdateIn]
)
SELECT
U.Id
,CA.Id
, '1' AS [Activo]
, GETDATE() AS [InsertAt] --obtiene la fecha del dia de insercion
, GETDATE() AS [UpdateAt] --obtiene la fecha del dia de actualizacion
, 'DB Admin' AS [InsertBy] --string de prueba
, 'DB Admin' AS [UpdateBy] --string de prueba
, 'Costa Rica' AS [InsertIn] --string de prueba
, 'Costa Rica' AS [UpdateIn] --string de prueba
FROM
@DocumentoXML.nodes('Operaciones/FechaOperacion[sql:variable("@punteroFecha")]/UsuarioPuedeVer ') AS t(d)
INNER JOIN [dbo].[Usuario] AS U ON d.value('@User', 'VARCHAR(100)') = U.Nombre
INNER JOIN [dbo].[CuentaAhorro] AS CA ON d.value('@NumeroCuenta', 'INT') = CA.NumeroDeCuenta
------------------------Movimiento------------------------------------------------
--crear un trigger despues de cada movimiento para que actualice a la cuenta
--para eso hacer un loop igual que para cuentas
--DISABLE TRIGGER TriggerActualizaCuenta ON [dbo].[Movimiento];
SELECT @LenMov = COUNT(O.f.value('@Tipo','INT'))--probar ahí si no probar con numeros de cuenta
FROM @DocumentoXML.nodes('Operaciones/FechaOperacion[sql:variable("@punteroFecha")]/Movimientos') AS O(f)
SET @IteradorMov=1
WHILE @IteradorMov<=@LenMov--para ir iterando sobre cada movimienot en cada nodo fecha
BEGIN
SELECT
@tipo = d.value('@Tipo', 'INT')
,@idCuenta = CA.Id
,@idEstado = dbo.FuncObtenerIdEstado (d.value('@CodigoCuenta', 'INT'), @FechaOperacion)--deberia retornar el id del estado de cuenta que corresponda
,@monto = d.value('@Monto', 'MONEY')
,@descripcion = d.value('@Descripcion', 'VARCHAR(200)')
,@nuevoSaldo = dbo.FuncObtenerNuevoSaldo (d.value('@CodigoCuenta', 'INT'), d.value('@Tipo', 'INT'), d.value('@Monto', 'MONEY') )
FROM
@DocumentoXML.nodes('Operaciones/FechaOperacion[sql:variable("@punteroFecha")]/Movimientos[sql:variable("@IteradorMov")]') AS t(d)
INNER JOIN [dbo].[CuentaAhorro] AS CA ON d.value('@CodigoCuenta', 'INT') = [NumeroDeCuenta]
--Se inserta el movimiento
SET TRANSACTION ISOLATION LEVEL READ COMMITTED
BEGIN TRANSACTION Actualizar
INSERT INTO [dbo].[Movimiento]
(
[IdTipoMovimiento]
,[IdCuentaAhorro]
,[IdEstadoDeCuenta]
,[Monto]
,[Fecha]
,[Descripcion]
,[NuevoSaldo]
)
VALUES (
@tipo
,@idCuenta
,@idEstado
,@monto
,@FechaOperacion
,@descripcion
,@nuevoSaldo
)
COMMIT TRANSACTION
-- Cuando se inserte el movimiento, se le cambia a la cuenta el nuevo saldo
UPDATE dbo.CuentaAhorro
SET
Saldo = @nuevoSaldo
WHERE
[Id] = @idCuenta
-------Se revisa si hay que cambiar el Saldo Minimo--------------------
SELECT @saldoMinimo= EC.SaldoMinimo FROM [dbo].[EstadoCuenta] AS EC WHERE EC.Id=@idEstado
IF @nuevoSaldo<@saldoMinimo
BEGIN
UPDATE [dbo].[EstadoCuenta]
SET
[SaldoMinimo]=@nuevoSaldo
WHERE Id=@idEstado
END
-------------Se suma los retiros CH y CA-----------------------------
IF (@tipo = 3 or @tipo = 5)
UPDATE dbo.EstadoCuenta
SET
QOCH = QOCH + 1
WHERE
[Id] = @idEstado
IF (@tipo = 2 or @tipo = 4)
UPDATE dbo.EstadoCuenta
SET
QOCA = QOCA + 1
WHERE
[Id] = @idEstado
----------------------------------------------------
SET @IteradorMov = @IteradorMov+1
END --WHILE PARA ITERAR MOVIMIENTOS
SET @punteroFecha = @punteroFecha + 1--para que recorra el siguiente nodo
--acá preguntar por los estados de cuenta que tiene FechaFinal = @fechaItera
EXECUTE dbo.SPCierreEstadoCuenta @fechaItera
--para hacer cierre de cuenta
SET @Iterador = @Iterador+1--incrementa los días
END --END DEL IF (@FechaOperacion = @fechaItera)
END --END DEL BEGIN DEL WHILE
Comentarios
Publicar un comentario