PDA

Ver la Versión Completa : tablas temporales en interbase


Manuel
03-06-2003, 01:28:50
hola amigos del foro, la única solución que me dan para imprimir un informe es juntar todas la tablas necesarias en una tabla "temporal", me dicen que no existe propiamente talen interbases, pero se pueden simular, la puedo crear con una sentencia Sql así:



create table TablaTmp(DatosTipos);

TablaTmp puede ser variable?

ahora esa tabla se borra así... ?????

Iván
03-06-2003, 08:42:36
La forma de simular la tabla temporal sería la siguiente, bajo mi punto de vista.

1.- Empieza el proceso donde necesitas la tabla temporal.

2.- Llegado el punto creas la tabla temporal con un nombre único. Create table XXX (....);
La tabla cuando la creas puede tener la estructura que quieras.

3.- La llenas de datos, haces todas las operaciones que quieras y la usas como necesites.

4.- Ya no la necesitas más, haces un drop tabla XXX.

5.- Terminas el proceso.

Es imprescindible que te aseguras de eliminar la tabla temporal al terminar el proceso que haces, ya que sino podrías provocar un aumento del tamaño impresionante de la BD si nunca borras las "temporales".

Por cierto, si trabajas en Delphi, igual te interesaría más que crear tablas temporales usar un TClientDataset, que a mi muchas veces me han evitado tener que usar tablas temporales.

Un saludo.

lbuelvas
03-06-2003, 10:06:25
Hola campeones,

interesante pregunta, pues bien si estas trabajando en Delphi podrias hacer como yo hago.

Lo primero es como bautizar una tabla temporal, desde mi punto de vista el nombre de la tabla debererian empezar por la palabra TEMPORAL_ (utilizo TEMP_) luego una palabra que indique el proposito (unr ejempo para montar unos carnes puede ser CARNE) y por ultimo el nombre del usuario porque puede ser que dos usuarios entren al mismo proceso y se armaria el lio.

Un ejemplo completo TEMP_CARNE_SYSDBA.

Lo segundo (y en eso contradigo de manera respetuosa a IVAN) es que solo debe crearse una vez si dicha tabla temporal es de frecuente uso.

Utilizio un codigo como este


if not _existe_tabla ('TEMP_CARNET_' + _user_name,IBTransaction1) then
_crear_tabla_sql('TEMP_SICARNETIZADOS_' + _user_name,
'ID_AFILIADO Integer Not Null PRIMARY KEY, ' +
'FECHA_ENTREGA DATE, ' +
'NUMERO_HOJA INTEGER',
IBTransaction1)
else
_prepara_sql(Query_Especial,'delete from TEMP_SICARNETIZADOS_' + _user_name);


loe explico, si no existe la tabla se crea, en caso contrario se limpia su contenido.

Tambien le coloco a los programas una opcion para que el administrador antes de hacer copias de seguridad (y con los usuarios afuera) elimine todas las tablas temporales, cosa que es muy facil pues todas las tablas temporales empiezan por el nombre TEMP_.

Aprovecho para preguntar a Ivan si el TClientDataset puede usarse con los IBX y de que manera pueden evitarse las tablas temporales

Iván
03-06-2003, 11:22:07
Buenas :)

Primero... me ha echo mucha gracia lo de que me contradigas de forma respetuosa.... Que yo también soy humano y me equivoco. Y así, si me contradices, también aprendo yo :)

Tienes razón en el sentido de que la tabla temporal si es de uso frecuente, pues es mejor tenerla todo el ratillo creada. Muy buena idea lo de crear la tabla con nombre de compuesto de TEMPORAL + el IDTransaccion. Así te aseguras de que la tabla no existirá.

Bueno, lo del TClientDataSet. A ver como lo explico fácilmente.

Normalmente, cuando requieres hacer listados, hay veces que juntar todos los datos directamente en un query es imposible, y si no lo es, la eficiencia de hacerlo en consultas separadas sería mayor. Para eso, en otros SGBD se suelen usar las tablas temporales en el sentido que yo las conozco.

Eso se puede simular usando un TClientDataSet, cargando allí los datos y haciendo las manipulaciones y nuevas consultas necesarias. El inconveniente es cuando tienes que recuperar muchos registros de una consulta, porque en ese caso si que realmente estas aumentando el tráfico de la red, pero los listados habituales sueles ser de 10-20 páginas y suelen ser de menos de 1000 registros, con lo cual para ese volumen de datos se puede asumir el sacrificio. Para un listado de 100.000 registros a recuperar, probablemente este sistema sería ineficiente.

Un saludo.

jceluce
03-06-2003, 13:49:48
Hola, me sumo al tema con mi experiencia personal.

Yo creo la tabla desde un principio y le agrego un campo numérico a la clave principal (por ej.: temp_nro). Además creo un generador para asignar este número.
La idea es que antes de generar la consulta en cuestión tomar un número desde el generador para asignarlo al campo temp_nro.
De esta manera puedo identificar los registros usados en la consulta.
Al final de la consulta puedo hacer un
DELETE from TEMPORAL whrere temp_nro = XXXX,
donde XXXX es el número que me devolvió el generador.
Además como en los listados normalmente no hay modificaciones de las tablas podemos aislar todo el proceso en una sola transacción y haciendo un Rollback al final liberamos todo (aun sin hacer el delete from temporal where temp_nro = xxx).
Esto me permite que varios usuarios, o el mismo en varias sesiones, puedan ejecutar el proceso en foema simultánea.

Iván
03-06-2003, 15:10:30
Al final todos los caminos llevan a Roma :)

Mi única duda es en el caso de tener muchos usuarios conectados y pidiendo ese mismo listado, si se vuelve lento o no al tener un mayor número de datos, aunque supongo que con unos buenos indices definidos, eso no debería pasar.

Además, está bien eso del Rollback, así te ahorras tener que borrar tú los datos y equivocarte :)

Otra forma que se me ha ocurrido, es montar una vista que nos agruparía la mayoría de los datos, de tal forma que prácticamente el listado que desearamos fuera un select sobre la vista. El inconveniente de este sistema es q se volvería un poco más lento la inserción/modificación/eliminación sobre un registro, al tenerse que actualizar la vista.

Bufff.... Como sigamos así, vamos a poder escribir un libro sobre como simular tablas temporales :)

A ver que nuevas ideas /mejoras surjen

Saludos.

Manuel
04-06-2003, 00:53:33
he implementado la solucion de Javier me ha gustado y hasta ahora ha andado muy bien. Gracias a todos por sus sugerencias, no descarto usar otro metodos que recomiendan aca. Gracias.

jwmoreira
11-06-2005, 01:23:21
Disculpa por opinar tarde y no se si tenga razón, pero yo aplicaría partde de lo que dice Javier, usar una tabla como generador pero solo para la numeración debido a la cantidad de Usuarios que puedan ejecutar ese proceso, ó, tambien que el mismo usuario ejecute varias veces la misma opción, yo usaría éste numero para crear tablas por cada numero, osea TMP_000001, no se en Firebird, pero he visto en otras bases que es más rápido hacer un DROP de una tabla que tiene 10000 registros que hacer un DELETE a todos esos registros, si estoy equivocado espero que me lo digan.

Saludos,
Jorge.

Manuel
13-06-2005, 14:45:06
Ahora estoy usando el método de crear una tabla temporal tmp_número, me parece mejor.