Está en la página 1de 24

Lógica de negocio.

Qué es la lógica de negocio?


Son las tareas relacionadas con los procesos
de un negocio, ejemplo: ventas, órdenes.
Ejemplo: Sólo las partes rojas pueden estar
en ‘Londres’
Lógica de negocio.

En que parte de la base de datos se


debe implmentar la lógica de negocio:
•Funciones.
•Store Procedures.
•Triggers.
Triggers
Un trigger es un código que automáticamente
es ejecutado en respuesta a ciertos eventos
sobre una tabla en particular dentro de una
base de datos.
Store Procedures
Es un programa o función el cual es
almacenado físicamente dentro del DBMS.
Su implementación varía de un DBMS a otro.
La ventaja de un procedimiento almacenado
es que al ser ejecutado, en respuesta a una
petición de usuario, es ejecutado
directamente en DBMS.
Función
CREATE OR REPLACE FUNCTION FSUMA_TOTALES
(
PCVE IN VARCHAR2
) RETURN NUMBER AS
ltot number;
CURSOR ctot IS
SELECT sum(vpy.cant) from jsilva.vpy vpy
WHERE vpy.CVE_V = pcve;
BEGIN
OPEN ctot;
FETCH ctot INTO ltot;
CLOSE ctot;
RETURN ltot;
END FSUMA_TOTALES;

select fsuma_totales ('V1') as total_proveedor from duAL;


Store Procedure
CREATE OR REPLACE PROCEDURE PSUMA_TOTALES
(
PCVE_V IN VARCHAR2
, OTOTAL OUT NUMBER
) AS
CURSOR ctot IS
SELECT sum(vpy.cant) from jsilva.vpy vpy
WHERE CVE_V = pcve_v;
BEGIN
OPEN ctot;
FETCH ctot INTO OTOTAL;
CLOSE ctot;
END PSUMA_TOTALES;
Store Procedure Ejecución
SET SERVEROUTPUT ON;
DECLARE
PCVE_V VARCHAR2(200);
OTOTAL NUMBER;
BEGIN
PCVE_V := 'V1';

PSUMA_TOTALES(
PCVE_V => PCVE_V,
OTOTAL => OTOTAL
);
DBMS_OUTPUT.PUT_LINE(ototal);
END;
Triggers
Row Triggers

Cada que se efectúa una operación sobre la tupla se acciona el trigger


Statement Triggers

Se ejecuta una sóla vez por todas las operaciones.


Ejecución Triggers

"BEFORE triggers“
Se ejecuta el trigger antes de ejecutarse la operación de insert, update, delete.
“AFTER triggers“
Se ejecuta el trigger despúes de ejecutarse la operación de insert,update o delete
AFTER triggers pueden modificar la misma tabla, otra tabla.
La diferencia en la activación entre ambos tipos de trigger refleja el propósito del
trigger.
BEFORE triggers en general son una extensión de las validaciones del DBMS por
lo tanto:
Se pueden ejecutar validaciones en los datos de entrada.
Generar nuevos valores para nuevos registros.
Leer otras tablas para obtener valores de referencia.
BEFORE triggers no son usados para modificar valores de la base de datos
debido a que el trigger es ejecutado antes de que los datos queden guardados en
la Base de datos.
AFTER triggers siempre ven la base de datos en un estado consistente, ya que
se ejecutan despúes de haberse ejecutado las validaciones de integridad.
Ejecución Triggers
Ejecución Triggers

Para una tabla dada con triggers de BEFORE y AFTER asociados el evento de
UPDATE, todos los triggers de BEFORE se ejecutan primero.
Si los triggers de UPDATE tienen lógica de actualización, se ejecutan las
actualizaciones las cuales quedan integradas como un resultado intermedio que
va pasando de un trigger a otro para tratar de mantener la consistencia de
valores.
Cuando todos los triggers de BEFORE han sido activados por el evento que lo
disparó, el resultado intermedio viaja como entrada a los triggers de AFTER.
Triggers
Los triggers se usan generalmente en:
INSERT event (as a new record is being inserted into the database).
UPDATE event (as a record is being changed).
DELETE event (as a record is being deleted).
Triggers
create table v_demotrig as select * from jsilva.v v;
CREATE SEQUENCE TSTAT_SEQ INCREMENT BY 1 START WITH 1
MAXVALUE 99999999999999999999 MINVALUE 1 NOCACHE ORDER;
CREATE TABLE TSTAT (
CVE_STAT INTEGER NOT NULL,
DESCRIPCION VARCHAR(100) NOT NULL,
CONSTRAINT "PK_TSTAT" PRIMARY KEY ("CVE_STAT")
);
CREATE OR REPLACE TRIGGER TIB_TSTAT
BEFORE INSERT ON TSTAT
FOR EACH ROW
DECLARE

BEGIN
SELECT TSTAT_SEQ.NEXTVAL INTO :NEW.CVE_STAT FROM DUAL;
END;
/
insert into tstat(descripcion) values ('ACTIVO');
insert into tstat(descripcion) values ('BORRADO');
commit;
select * from tstat;
Triggers Valida Inserción e inserta en histórica
alter table v_demotrig add cve_stat integer null;
update V_DEMOTRIG set cve_stat = 1 ;
commit;
alter table v_demotrig MODIFY cve_stat integer not null;
alter table v_demotrig add constraint fk_stat_demotrig
foreign key (cve_stat) references tstat (cve_stat);
Triggers Valida Inserción e inserta en histórica
CREATE TABLE V_DEMOTRIG_H
(
CVE_DEMOTRG_H integer not null,
CVE_V VARCHAR2(3) NOT NULL,
PROVEEDOR VARCHAR2(50),
STATUS NUMBER,
CIUDAD VARCHAR2(50),
CVE_STAT NUMBER NOT NULL,
modificado_por varchar(100) not null,
modificado_en date,
creado_por varchar(100) not null,
creado_en date,
ACCION VARCHAR(100) not null,
CONSTRAINT "PK_CVE_H" PRIMARY KEY ("CVE_DEMOTRG_H")
);
CREATE SEQUENCE V_DEMOTRIG_H_SEQ INCREMENT BY 1 START WITH 1 MAXVALUE
99999999999999999999 MINVALUE 1 NOCACHE ORDER;

CREATE OR REPLACE TRIGGER TIB_V_DEMOTRIG_H


BEFORE INSERT ON V_DEMOTRIG_H
FOR EACH ROW
DECLARE

BEGIN
SELECT V_DEMOTRIG_H_SEQ.NEXTVAL INTO :NEW.CVE_DEMOTRG_H FROM DUAL;
END;
/
Triggers Valida Inserción e inserta en histórica
CREATE OR REPLACE TRIGGER TIB_DEMOTRIG
BEFORE INSERT ON V_DEMOTRIG
FOR EACH ROW
DECLARE
ltot number;
luser V_DEMOTRIG_H.MODIFICADO_POR%TYPE;

CURSOR cnombre IS
SELECT count(1) FROM v_demotrig v
WHERE UPPER(v.PROVEEDOR) = UPPER(:NEW.proveedor);
BEGIN
ltot := 0;
OPEN cnombre;
FETCH cnombre INTO ltot;
CLOSE cnombre;

IF ltot >= 1 THEN


RAISE_APPLICATION_ERROR(-20000,'El proveedor ' || :NEW.PROVEEDOR || ' ya existe.');
END IF;
select user into luser from dual;
insert into V_DEMOTRIG_H(CVE_V, PROVEEDOR, STATUS, CIUDAD, CVE_STAT,
MODIFICADO_POR, MODIFICADO_EN, CREADO_POR, CREADO_EN, ACCION)
values (:NEW.CVE_V, :NEW.PROVEEDOR, :NEW.STATUS, :NEW.CIUDAD, :NEW.CVE_STAT,
luser, sysdate, luser, sysdate, 'INSERT');
END;
/
Triggers Valida Inserción Testing
Insert into v_demotrig(cve_v, proveedor, status,ciudad)
Values('VTI', 'Smith', 20,'DF');
Commit;

Insert into v_demotrig (cve_v, proveedor, status,ciudad, cve_stat)


Values('VTI', 'Smith ok', 20,'DF',1);
Commit;
Triggers

UPDATE event (as a record is being changed).

create or replace TRIGGER TUB_V_DEMOTRIG


BEFORE UPDATE ON V_DEMOTRIG
FOR EACH ROW
DECLARE
luser V_DEMOTRIG_H.MODIFICADO_POR%TYPE;

BEGIN
IF :NEW.PROVEEDOR <> :OLD.PROVEEDOR OR
:NEW.STATUS <> :OLD.STATUS OR
:NEW.CIUDAD <> :OLD.CIUDAD OR
:NEW.CVE_STAT <> :OLD.CVE_STAT
THEN

select user into luser from dual;


insert into V_DEMOTRIG_H(CVE_V, PROVEEDOR, STATUS, CIUDAD, CVE_STAT,
MODIFICADO_POR, MODIFICADO_EN, CREADO_POR, CREADO_EN, ACCION)
values
(:NEW.CVE_V, :NEW.PROVEEDOR, :NEW.STATUS, :NEW.CIUDAD, :NEW.CVE_STAT,
luser, sysdate, luser, sysdate, 'UPDATE');

END IF;
END;
/
Triggers

UPDATE event (as a record is being changed).

update V_DEMOTRIG set ciudad = 'Londres' WHERE cve_v = 'VTI';


commit;
Select * from V_DEMOTRIG;
update V_DEMOTRIG set status = 400 WHERE cve_v = 'VTI';
commit;
Triggers
DELETE event (as a record is being deleted).

create or replace TRIGGER TDB_V_DEMOTRIG


BEFORE DELETE ON V_DEMOTRIG
FOR EACH ROW
DECLARE
ltot number;
luser V_DEMOTRIG_H.MODIFICADO_POR%TYPE;
BEGIN
ltot := 0;
SELECT FSUMA_TOTALES(:OLD.cve_v) into ltot FROM dual;
IF ltot >= 50 THEN
RAISE_APPLICATION_ERROR(-20000,'El proveedor '|| :OLD.PROVEEDOR || ' ya tiene pedidos.');
END IF;
select user into luser from dual;
insert into V_DEMOTRIG_H(CVE_V, PROVEEDOR, STATUS, CIUDAD, CVE_STAT,
MODIFICADO_POR, MODIFICADO_EN, CREADO_POR, CREADO_EN, ACCION)
values (:OLD.CVE_V, :OLD.PROVEEDOR, :OLD.STATUS, :OLD.CIUDAD, :OLD.CVE_STAT,
luser, sysdate, luser, sysdate, 'BORRADO');

END;
/
Triggers
DELETE event (as a record is being deleted).

Delete from V_DEMOTRIG where cve_v = 'V1';


Commit;
Delete from V_DEMOTRIG where cve_v = 'VTI';
Commit;
Triggers
Triggers

Trigger ‘A’ fires Trigger B

Fires Trigger
Table Inserts
Trigger Trigger
‘ A’ ‘B’

Trigger ‘B’ fires Trigger A


Temp

También podría gustarte