Está en la página 1de 9

Memoria:

Practica Java.
Opcin A: Realizar un programa Java que permita regenerar un esquema de base de datos que fue exportado anteriormente con el programa PL/SQL realizado en la primera prctica.

Grupo: Daniel Gonzlez Postigo. Guillermo Garca Martn Pablo Garca Andrs Sandro Guerrero Duarte

Forma en la que atacamos el problema.


En principio planteamos el como hacer el programa si construir los comandos respecto leamos el fichero o lo almacenbamos en estructuras. Finalmente nos decidimos por las estructuras, pues no sera mas cmodo sobre todo a la hora de priorizar la creacin de unas restricciones sobre otras. Podemos decir que un esquema rpido de nuestro programa seria tal que: Interfaz Lectura Comandos Conexin XML

Interfaz

En la interfaz bsicamente es donde nosotros especificamos nuestros datos de conexin a la base de datos, y donde seleccionaremos el fichero XML a cargar . Para ello nos vamos a Archivo -> Abrir o usamos el comando rpido Ctrl+o y nos aparecer una ventana de exploracin donde podremos elegir nuestro fichero.

Establecimiento de conexin La conexin la establecemos desde la clase pracjava .


public void Conexion() throws SQLException, FileNotFoundException, IOException { Comandos comand; DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver()); //Establecemos la conexin. Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@"+Host+":"+Pu erto.trim()+":"+SID,usuario,pass); Generador lectura = new Generador();//Leemos el fichero lectura.BBDD(Fichero); Statement stmt = conn.createStatement(); //Generamos los comandos comand=new Comandos(lectura.tablas,lectura.restricciones,stmt,jDialog1,jDial og2,jDialog3); String wiki = comand.Comandostablas(); String waka = comand.Comandosrestriccion(); //Cerramos la conexin stmt.close(); }

Estructuras Elegidas y Generacin de comandos.


Hemos dividido toda la informacin en dos clases principales, que son restriccin y atributo. nom_restriccion lo usamos para el nombre de la restriccin, tabla almacena el nombre de la tabla, tipo almacena el tipo de restriccin P (Primary key ) C (Check) R ( Foreign Key ) U (Unique), tabla_ref lo empleamos en caso de que sea foreign key para almacenar a la tabla a la que apunta, condicin almacena la condicin que almacena en caso de ser Check y columnas lo empleamos por si en la restriccin se

emplea mas de una columna , por ejemplo primary key compuesta o foreign key compuesta. public class Atributo { private String nombre; private String tipo; private String longitud; En nombre almacenamos el nombre del atributo, en tipo el tipo de variable que almacena el atributo , y su longitud en caso de que tenga. Todas las restricciones son almacenadas en una estructura tal que as: restricciones = new HashSet<Restriccion>(); Y las tablas con sus atributos en una estructura tal que as: tablas= new HashMap<String,Set<Atributo>>(); De esta forma para crear nuestras tablas, lo primero que hacemos es crear las tablas con sus respectivos atributos. Para ello creamos un parte genrica que ser CREATE TABLE <NOM_TABLA>( <NOM_ATRIBUTO><TIPO><LONGITUD>, ) Y vamos iterando por el map hasta crear todas las tablas con sus atributos. Lo hacemos con el siguiente cdigo: String comando="CREATE TABLE "+e.getKey()+ "("; String Atributos=""; Set<Atributo> aux = (Set<Atributo>) e.getValue(); Iterator it = aux.iterator(); Atributo elem; elem=(Atributo) it.next(); if(elem.getTipo().compareToIgnoreCase("")==0 || elem.getTipo().compareToIgnoreCase("DATE")==0) { Atributos=Atributos+" \n"+elem.getNombre()+" "+elem.getTipo(); //Atributos sin tamao especifico } else

{ Atributos=Atributos+" \n"+elem.getNombre()+" "+elem.getTipo() + "(" + elem.getLongitud()+ ")"; } while(it.hasNext()) { elem=(Atributo) it.next(); if(elem.getTipo().compareToIgnoreCase("")==0 || elem.getTipo().compareToIgnoreCase("DATE")==0) { Atributos=Atributos+", \n"+elem.getNombre()+" "+elem.getTipo(); //Atributos sin tamao especifico } else { Atributos=Atributos+",\n"+elem.getNombre()+" "+elem.getTipo() + "(" + elem.getLongitud()+ ")"; } } comando=comando+Atributos+")"; Una vez hemos creado todas las tablas con sus atributos, creamos nuestras restricciones con un cierto orden. La principal importancia era crear las Primary key antes que las Foreing key pues nos produce un error si referenciamos a una tabla la cual no contiene una Primary. Para crear las restricciones iteramos a lo largo del set de restricciones y clasificando las restricciones por su Tipo de esta forma podemos priorizar unas sobre otras. if(res.getTipo().compareToIgnoreCase("C")==0) { comando="ALTER TABLE "+res.getTabla()+" MODIFY ("; comando=comando + " CONSTRAINT " + res.getNombre() + " CHECK(" + res.getCondicion() + ")" ;

comando=comando+" ) "; System.out.println(comando); //Deteccin de errores y envio del comando. } else if (res.getTipo().compareToIgnoreCase("U")==0) { comando="ALTER TABLE "+res.getTabla()+" MODIFY ("; Iterator ite = res.getColumnas().iterator(); comando= comando + " " + ite.next() + " CONSTRAINT " + res.getNombre() + " UNIQUE "; comando=comando+" ) "; System.out.println(comando); //Deteccin de errores y envio del comando. } else if (res.getTipo().compareToIgnoreCase("P")==0) { comando="ALTER TABLE "+res.getTabla()+" MODIFY ("; comando= comando + " CONSTRAINT " + res.getNombre() + " PRIMARY KEY("; Iterator itt= res.getColumnas().iterator(); comando=comando+" "+ itt.next(); while(itt.hasNext()) { comando=comando+", "+ itt.next(); } comando=comando+" )"; comando=comando+" ) "; System.out.println(comando); //Deteccin de errores y envo del comando. } public void CreaForeign(Restriccion res) throws SQLException { if (res.getTipo().compareToIgnoreCase("R")==0) { String comando="ALTER TABLE "+res.getTabla()+" MODIFY (";

comando=comando+" CONSTRAINT "+ res.getNombre() + " FOREIGN KEY(" ; Iterator Ite= res.getColumnas().iterator(); comando=comando+Ite.next(); while(Ite.hasNext()) { comando=comando+","+Ite.next(); } comando=comando+ ")"+" REFERENCES "+ res.getTablaRef(); comando=comando+" ) "; System.out.println(comando); //Deteccin de errores y envo de comando. }

Deteccin de errores.
Los errores principales que detectamos y avisamos son el caso de que ya existiera una tabla con ese nombre, restricciones con el mismo nombre , Primary key con ese mismo nombre . Estos errores los controlamos debido a que al volcar la base de datos tambin almacenamos los nombres, y aprovechando esto tambin los cargamos. El error 955: Es el error de creacin de tabla con un nombre que ya existe. try { try { rset = stmt.executeQuery(comando); } catch(java.sql.SQLSyntaxErrorException errnom){ if (errnom.getErrorCode()==955) { System.out.println(errnom.getErrorCode()); MostrarErrores(errnom.toString()); } }

El primer try se encarga de controlar las excepciones diferentes a la 955 que es la que controlamos en este caso. El error 2264: Es el error de creacin de una restriccin con un nombre que ya existe. El error 2261: Es el error de creacin de una Primary Key con un nombre que ya existe. try { try { rset = stmt.executeQuery(comando); } catch (SQLSyntaxErrorException ex) { if (ex.getErrorCode()==2264) { this.jrestricc.setVisible(true); this.jrestricc.setTitle("Error: Restriccin existente"); } else if (ex.getErrorCode()==2261) { this.jPrimary.setVisible(true); } } }

Problemas encontrados y como los hemos solucionados


El mayor problema de todos fue la sincronizacin entre la primera practica y la tercera, sobre la cual tuvimos que hacer modificaciones para adaptarlo a la tercera practica, un error bastante grande que nos dimos cuenta de ultima hora , fue al almacenar las restricciones, almacenbamos tambin restricciones basura del tipo bin que no afectaban a ninguna de las tablas de nuestra base de datos, para ello lo que hicimos fue modificar el puntero con un where para que solo cogiera nuestras tablas. Otro problema grave fue que se nos olvid almacenar la tabla a la que referenciaban las foreign , estoy lo solucionamos pues en user_constraints aparece la R_constraint_name que es el nombre de la contraint a la que referencia la foreign y buscando en user_cons_columns sacamos el nombre de la tabla.

Posibles mejoras
-Como posibles mejoras se podra hacer que no almacenara los nombres de las constraints de esta forma evitaramos la colisiones de nombres. -Ejecucin de procesos empleando threads.