create or replace trigger trCuentaBancaria
before insert on giro
for each row
declare
vSaldoCuenta Cuenta.saldo%type;
vSaldoLinea LineaCredito.saldo%type;
vIdLinea LineaCredito.idLinea%type;
vLineaUsada LineaCredito.saldo%type;
vTotalDisponible LineaCredito.saldo%type;
NO_HAY_FONDOS EXCEPTION;
err_num NUMBER;
err_msg VARCHAR2(255);
begin
dbms_output.put_line('idGiro : '||:new.idGiro);
dbms_output.put_line('idCuenta : '||:new.idCuenta);
dbms_output.put_line('Fecha : '||:new.fecha);
dbms_output.put_line('Monto : '||:new.monto);
-- Obtenemos el saldo de la cuenta corriente
select saldo into vSaldoCuenta
from Cuenta
where idCuenta = :new.idCuenta;
dbms_output.put_line('Monto Solicitado : '||:new.monto|| ' Saldo en Cuenta Corriente : '|| vSaldoCuenta);
if :new.monto <= vSaldoCuenta then
update Cuenta
set saldo = saldo - :new.monto
where idCuenta = :new.idCuenta;
else
-- Obtenemos el saldo en la linea de credito
select saldo, idLinea into vSaldoLinea, vIdLinea
from LineaCredito
where idCuenta = :new.idCuenta;
vTotalDisponible := vSaldoCuenta + vSaldoLinea;
dbms_output.put_line('Monto Solicitado : '||:new.monto|| ' Saldo en Cuenta Corriente : '|| vSaldoCuenta || 'Saldo en linea de Credito : '||vSaldoLinea);
dbms_output.put_line('Total Disponible : '||vTotalDisponible);
if :new.monto > vTotalDisponible then
-- Si No tenemos suficiente dinero se anula la operación
RAISE NO_HAY_FONDOS;
else
-- Ocupo todo el saldo de la Cuenta Corriente
update Cuenta
set saldo = 0
where idCuenta = :new.idCuenta;
-- y el resto lo obtenemos de la linea de credito
vLineaUsada := :new.monto - vSaldoCuenta;
update LineaCredito
set saldo = saldo - vLineaUsada
where idLinea = vIdLinea;
-- Ahora se inserta un registro en la tabla UsoLinea
insert into UsoLinea (idUso,idLinea,fecha,monto) values(seqUsoLinea.NextVal,vIdLinea, sysdate,vLineaUsada);
end if;
end if;
EXCEPTION
WHEN NO_DATA_FOUND THEN
dbms_output.put_line('Cuenta no encontrada *************** : '||:new.idCuenta);
RAISE_APPLICATION_ERROR(-20001, '*** Error *** => Cliente no posee linea de credito y su saldo es insuficiente');
WHEN NO_HAY_FONDOS THEN
RAISE_APPLICATION_ERROR(-20000, '*** Error *** => No hay suficiente dinero para su transacción');
WHEN OTHERS THEN
err_num := SQLCODE;
err_msg := SQLERRM;
DBMS_OUTPUT.put_line('Error: '||TO_CHAR(err_num));
DBMS_OUTPUT.put_line(err_msg);
END;