PDA

Ver la Versión Completa : exportar a un script sql para luego restaurar a otra BD pero igual metadata


pvizcay
08-06-2007, 22:32:02
hola amigos del foro,:confused:

aca les dejo una cuestión que se me plantió a ver si alguien la soluciono primero..

tengo que agregarle a mi aplicación una función de exportación a un script sql (con DML Insert Into) para integrar la información en otra base de datos; osea no es un backup completo de la base que necesito, sino mas bien una exportación "selectiva" de los datos que el usuario necesite..

el principal tema es que en mi base de datos utilizo todas claves surrogativas o en lenguaje común IDs con generadores.. y en la base de datos destino esos generadores pueden ir en otra secuencia completamente distinta, por lo que necesito que se generen nuevamente (sino se puede dar que con el ID que estoy exportando ya exista en la BD de destino y viole el constraint primary key).. pero si en el script hago un gen_id(GEN, 1) en el valor de la PK, ¿cómo hago para enganchar ese valor con lo que se inserta en las tablas que tienen FK (claves extranjeras) a esa?

ejemplifico:
supongamos esta estructura sencilla
CREATE TABLE EMPRESA(ID Integer, ...)
CREATE TABLE FACTURA(ID Integer, ID_EMPRESA Integer, ...)
CREATE TABLE DETALLE(ID Integer, ID_FACTURA Integer, ...)

no puedo exportar los valores de los IDs al script por lo antes mencionado..

y si hago:
INSERT INTO EMPRESA(gen_id(GEN_EMPRESAS, 1), 'FULANITO SA', ...)
...
...

después cuando exporto los valores de las facturas de esa empresa

INSERT INTO FACTURA(gen_id(GEN_FACTURAS,1), ???, ....)

ahora no se con que ID se generó la empresa que exporte y que va en los signos "???"..

creo que se entiende bastante bien, ¿alguna sugerencia?

gracias desde ya, pablo

jachguate
09-06-2007, 05:40:08
Se me ocurren dos posibles soluciones:

si tu estructura lo permite:

Recordá que el segundo parámetro de la función gen_id es el avance del generador, así podrías hacer:


insert into empresa(gen_id(gen_empresas, 1), 'FULANITO SA', ...);
insert into factura(gen_id(gen_facturas, 1), gen_id(gen_empresas, 0), 'A1'...);
insert into detalle_factura(gen_id(gen_detfacturas, 1), gen_id(gen_factura, 0), 123);
insert into detalle_factura(
...
insert into factura(gen_id(gen_facturas, 1), gen_id(gen_empresas, 0), 'A2'...);
insert into detalle_factura(gen_id(gen_detfacturas, 1), gen_id(gen_factura, 0), 123);
...
insert into empresa(gen_id(gen_empresas, 1), 'FULANITO 2', ...);
insert into factura(gen_id(gen_facturas, 1), gen_id(gen_empresas, 0), 'A1'...);
..


El problema es que con una estructura medianamente compleja, esto ya no es posible.

Para estos otros casos, se me ocurre otra solución:

primero, crear una tabla de equivalencia entre ID's, algo como:


create table idequiv (
id integer not null primary key,
tabla_origen varchar(20),
id_origen integer,
id_destino integer
);

create generator gen_idequiv;
create index idequiv_idorigen on idequiv(tabla_origen, id_origen);


Esta tabla servirá para "recordar" el id en la base de datos de origen, así que el script de traslado podría lucir como:


--primero salvamos, el ID del registro que estamos procesando, en este caso la empresa 1, y generamos el nuevo.
insert into idequiv(gen_id(gen_idequiv, 1), 'EMPRESA', 1, gen_id(gen_empresas, 1));
-- ahora usamos ese valor dondequiera que requiramos el id de la empresa valiendonos del id en la base de origen
insert into empresa((select id_destino from idequiv where tabla_origen = 'EMPRESA' and id_origen = 1), 'FULANITO SA', ...);
insert into idequiv(gen_id(gen_idequiv, 1), 'EMPRESA', 2, gen_id(gen_empresas, 1));
insert into empresa((select id_destino from idequiv where tabla_origen = 'EMPRESA' and id_origen = 2), 'FULANITO 2', ...);

insert into idequiv(gen_id(gen_idequiv, 1), 'FACTURA', 1, gen_id(gen_facturas, 1));

insert into factura((select id_destino from idequiv where tabla_origen = 'FACTURA' and id_origen = 1), (select id_destino from idequiv where tabla_origen = 'EMPRESA' and id_origen = 1), 'A1'...);
insert into detalle_factura(gen_id(gen_detfacturas, 1), (select id_destino from idequiv where tabla_origen = 'FACTURA' and id_origen = 1), 0), 123);
insert into detalle_factura(


En la aplicación que genera el script, sería sencillo añadir funciones que dada una tabla y un id del registro, generen la sentencia de inserción y el subquery a utilizar. El modelo se simplificaría si se usara un único generador para todas las tablas.

Si es una base de datos que aún no está en producción, hay otras formas de enfrentar este problema.

Hasta luego.

;)

pvizcay
09-06-2007, 17:31:46
jachguate, gracias por tu respuesta :cool:

el gen_id(xx, 0) no se me había ocurrido, y funciona bien siempre que el script se genere con las dependencias correctas en orden.. si bien la estructura de mi base de datos dista de ser simple, estuve examinando y la solución que propones calza justo..

otra cosa que se me ocurre es que la base de datos donde se realiza la importación tiene que estar parada, porque como los generadores son globales si justo alguien esta ingresando alguna dato.. zasss sobreviene el desastre...! tendré que ponerme a estudiar los componentes administrativos para ver con cual puedo verificar esto..

ahora me pregunto, para generar dicho script, más allá de escribir todo el código a mano (no puedo utilizar herramientas como ibexpert, etc. porque tiene que ser una función de mi aplicación, además que no conozco ninguna herramienta que permita personalizar el orden en que se exportan los datos por las dependencias)

hay alguna librería o algo de que agarrarme como para no empezar de cero??

gracias desde ya!

rastafarey
13-06-2007, 20:31:13
Pero simplemente has un bakup y u restores.

y luego reorgaizas los identificadores nuevamente

como: pones el genrador a cero y coimensas reasiganr los ids nuevamente.
Yo uso este metodo para todas las tablas cada ves que le hago mantenimiento a sistemas que he echo.

sitrico
14-06-2007, 01:43:45
Abriste otro hilo con la misma duda :mad:

bueno te igual contesto :rolleyes:

Si te entendí bien el problema que tienes es que no sabes que ID le tocará a los registros exportados y por tanto no podrás enlazarlos apropiadamente con sus dependientes.

Puedes hacer lo siguiente:

Creas un campo "CLAVEALTERNA" que guarde el valor original del ID, Al generar el Script guardas el ID en ese campo y dejas el ID en NULL (lo asignará el trigger. Luego cuando importes la data buscas la relación por CLAVEALTERNA y ajustas los ID. Tambien te recomendaría recuperar a tablas temporales y luego de los ajustes correspondientes pasarlo a las definitivas.

No debe ser mayor problema (aunque no es facil) si controlas tanto la exportación como la importación.

¿ Tiene que ser con Scripts ?