Mostrando entradas con la etiqueta BD. Mostrar todas las entradas
Mostrando entradas con la etiqueta BD. Mostrar todas las entradas

jueves, 25 de febrero de 2010

¿Que son tablas mutantes?

Pues una tabla mutante o que esta mutando, es aquella que esta siendo modificada, ya sea por un INSERT, un DELETE o un UPDATE o una tabla que podría modificarse por los efectos de un ON DELETE CASCADE.

Por otro lado en este tipo de tablas hay dos tipos de restricciones, las cuales se presentan a continuación:

1. Las instrucciones de un row trigger no pueden ni leer ni modificar una tabla que está mutando.

2. Las instrucciones de un row trigger no pueden cambiar ni la clave primaria, ni claves foráneas, ni atributos únicos de tablas que estén restringiendo. Esta restricción tiene una excepción: un before row trigger disparado por un INSERT de una sola fila de una tabla con una clave foránea, puede modificar cualquier columna de la tabla primaria siempre que no se viole ninguna de las restricciones de integridad referencial.

Los ERRORES por Tablas Mutantes se detectan y se generan en Tiempo de Ejecución y no de Compilación (ORA-4091).


Ejemplo de Tablas Mutantes

A continuación la descripción de el disparador que da lugar a las tablas mutantes.

Este será un disparador que modifique el número de empleados de un departamento (columna Departamentos.Num_Emp) cada vez que sea necesario. Ese número cambia al INSERTAR o BORRAR uno o más empleados, y al MODIFICAR la columna Dpto de la tabla Empleados, para uno o varios empleados. La tabla Departamentos es una tabla de restricción de la tabla Empleados, pero el Disparador es correcto, porque modifica Num_Emp, que no es la clave primaria. Este disparador no puede consultar la tabla Empleados, ya que esa tabla es mutante (por ejemplo, esta instrucción no sería válida: SELECT COUNT(*) INTO T FROM Empleados WHERE Dpto = :new.Dpto;)

CREATE OR REPLACE TRIGGER Cuenta_Empleados
BEFORE DELETE OR INSERT OR UPDATE OF Dpto ON Empleados
FOR EACH ROW
BEGIN
IF INSERTING THEN
UPDATE Departamentos SET Num_Emp = Num_Emp+1
WHERE NumDpto=:new.Dpto;
ELSIF UPDATING THEN
UPDATE Departamentos SET Num_Emp = Num_Emp+1
WHERE NumDpto=:new.Dpto;
UPDATE Departamentos SET Num_Emp = Num_Emp-1
WHERE NumDpto=:old.Dpto;
ELSE
UPDATE Departamentos SET Num_Emp = Num_Emp-1
WHERE NumDpto=:old.Dpto;
END IF;
END;

El disparador anterior Cuenta_Empleados tiene un inconvenientes: modifica el campo Num_Emp aunque este no tenga el valor correcto.


Ejemplo de la solución para las Tablas Mutantes


Ahora bien basándonos en el ejemplo anterior de tablas mutantes, se escribirá la solución basándonos en la creación de dos nuevos disparadores, uno a nivel de fila y el otro a nivel de after, a continuación se escribira:


CREATE OR REPLACE PACKAGE Empleados_Dpto AS
TYPE T_Dptos IS TABLE OF Empleados.Dpto%TYPE
INDEX BY BINARY_INTEGER;
Tabla_Dptos T_Dptos;
END Empleados_Dpto;
CREATE OR REPLACE TRIGGER Fila_Cuenta_Empleados
AFTER DELETE OR INSERT OR UPDATE OF Dpto ON Empleados FOR EACH ROW
DECLARE Indice BINARY_INTEGER;
BEGIN
Indice := Empleados_Dpto.Tabla_Dptos.COUNT + 1;
IF INSERTING THEN
Empleados_Dpto.Tabla_Dptos(Indice) := :new.Dpto;
ELSIF UPDATING THEN
Empleados_Dpto.Tabla_Dptos(Indice) := :new.Dpto;
Empleados_Dpto.Tabla_Dptos(Indice+1):= :old.Dpto;
ELSE Empleados_Dpto.Tabla_Dptos(Indice) := :old.Dpto;
END IF;
END Fila_Cuenta_Empleados;
CREATE OR REPLACE TRIGGER Orden_Cuenta_Empleados
AFTER DELETE OR INSERT OR UPDATE OF Dpto ON Empleados
DECLARE Indice BINARY_INTEGER;
Total Departamentos.Num_Emp%TYPE;
Departamento Departamentos.NumDpto%TYPE;
BEGIN
FOR Indice IN 1..Empleados_Dpto.Tabla_Dptos.COUNT LOOP
Departamento := Empleados_Dpto.Tabla_Dptos(Indice);
SELECT COUNT(*) INTO Total FROM Empleados WHERE Dpto = Departamento;
UPDATE Departamentos SET Num_Emp = Total WHERE NumDpto = Departamento;
END LOOP;
Empleados_Dpto.Tabla_Dptos.DELETE;
END Orden_Cuenta_Empleados;


Exitos!!!!

martes, 30 de junio de 2009

Mi primer ABC en JPA

Hola q tal, hoy voy a mostrar un poco de codigo sobre JPA, el cual es un ORM muy facil y sencillo de utilizar.

Es un ABC ya que seran tres metodos que haran Altas (inserciones) Bajas (eliminaciones) Cambios (modificaciones) en la Base de datos, en este caso usaremos MySQL y NetBeans.

Altas:
Pues emezaremos con las inserciones a la base de datos, el codigo seria el siguiente:

public void addJugador(Jugador jugador) {
EntityManager em = getEntityManager();
try{
EntityTransaction entr=em.getTransaction();
entr.begin();
em.persist(jugador);
entr.commit();
} finally {
em.close();
}
}

Esto es solo si creamos con anterioridad un objeto tipo Jugador para darle persist, ahora en el caso de que tengamos que obtener los datos de algun formulario, podria ser el siguiente codigo:

public void addJugador() {
EntityManager em=emf.createEntityManager();
try{
EntityTransaction entr=em.getTransaction();
entr.begin();
Jugador newJugador=new Jugador();
jugador.setColor("Azul");
// o jugador.setColor(jTextField.getText());
jugador.setDescripcion("Este es un ejemplo.");
//o jugador.setDescripcion(jTextField2.getText());
em.persist(jugador);
entr.commit();
System.out.println("Ingreso exitoso ala base de datos.");
}
catch(Exception e){
System.out.println(e.getMessage());
}
finally{
em.close();
}
}


Bajas:
Para poder eliminar un objeto o bien una tupla de la base de datos.

public void removeJugador(Jugador jugador) {
EntityManager em = getEntityManager();
try{
EntityTransaction entr=em.getTransaction();
entr.begin();
Jugador deleteJugador = em.find(Jugador.class, jugador.getJugador());
em.remove(deleteJugador);
entr.commit();
} finally {
em.close();
}
}

Igual que en el anterior el objeto Jugador que se pasa por parametro puede tomarse de otro lado, un jTable, una Lista, etc.


Cambios:
Ahora para modifcar informacion podemos hacer lo siguiente:

public void updateJugador(Jugador jugador) {
EntityManager em = getEntityManager();
try{
EntityTransaction entr=em.getTransaction();
entr.begin();
Jugador changeJugador = em.find(Jugador.class, jugador.getJugador());
changeJugador.setColor("Verde");
changeJugador.setDescripcion("Una modificacion a la BD.");
entr.commit();
} finally {
em.close();
}
}


Por si lo necesitan, pueden descargar el archivo rar del siguiente link, seria grandioso ya que ahi podran encontrar lo siguiente:

- El script de la tabla de la base de datos que estaremos manipulando.
- El mapeo de la tabla al objeto Jugador.java
- El archivo que tiene los metodos del ABC.


Estoy pensando hacer mini videos tutoriales para poder mostrar un poco mas a detalle esto de JPA, ojala los pueda subir pronto ;)


Exitos!!!!!