El escenario es el siguiente:
"un sistema tipo CRM con múltiples usuarios operando al mismo tiempo, hay ciertas tablas críticas en el
sistema para las que nos interesa saber QUIEN CUANDO y DONDE las modificadan. A esto llamaremos sistema de historial de cambios
o tracking system".
Entonces, queremos registrar para cada cambio (INSERT, UPDATE, DELETE) la siguiente informacion:
1 fecha
2 usuario
3 programa
4 tabla involucrada
5 operacion (INSERT, UPDATE, DELETE)
Hay 2 formas que se me ocurren de resolver este asunto, una es incorporar la informacion del historial justo ANTES de realizar
el cambio. Esto implica modificar TODOS los programas que operen sobre el conjunto de tablas de interés (ardua tarea).
La otra opción es usando triggers a nivel tabla.
ejemplo: sea "Clientes" el nombre de la tabla de clientes del sistema
inicialmente teniamos este código:
create Clientes. /* creo 1 registro nuevo en clientes */
assign
Clientes.cliente-id = next-value(clientes-seq)
Clientes.razon-social = "cliente1"
Clientes.direccion = "direccion1"
Clientes.telefono = "telefono1"
.
notas:
clientes-id es la clave primaria de la tabla Clientes
clientes-seq es el nombre de la secuencia que nos permite generar el siguiente clientes-id
Entonces generamos 2 triggers: 1 para INSERT y UPDATE y el otro para DELETE
TRIGGER PROCEDURE FOR WRITE OF Clientes OLD BUFFER oldBuffer.
DEF VAR id LIKE historial-cambios.historial-cambios-id NO-UNDO.
DEF VAR id2 LIKE historial-cambios.historial-cambios-id NO-UNDO.
DEF VAR operacion_ LIKE historial-cambios-detalle.operacion NO-UNDO.
DEF VAR filtro_ LIKE historial-cambios-detalle.filtro NO-UNDO.
DEF VAR nom_tabla AS CHAR NO-UNDO INITIAL "Clientes".
IF (oldBuffer.cliente-id = Clientes.cliente-id) THEN
DO:
operacion_ = "UPDATE".
filtro_ = "cliente-id=" + STRING(Clientes.cliente-id).
END.
ELSE
DO:
operacion_ = "INSERT".
filtro_ = "".
END.
create historial-cambios.
assign
id = NEXT-VALUE(historial-cambios-seq)
historial-cambios-id = id
historial-cambios.fecha = NOW
historial-cambios.operador = /* NOMBRE DEL OPERADOR */
programa = program-name(1)
.
notas:
si no tenemos el nombre del operador, podemos almacenar el nombre de su equipo que se encuentra en la tabla virtual de sistema _connect.Connect-device
Espero les ayude, a mi me resultó.
saludos,
Walter |
| Publicado por: wm mk | 25/02/2009 15:12:03 | IP: 200.55.10.227 |