Hacer Query de una tabla, modificar, añadir o eliminar registros de este query y al final, actualizar tabla origen

780 views
Skip to first unread message

Sergio Ps

unread,
Feb 2, 2015, 4:18:47 AM2/2/15
to publice...@googlegroups.com
Buenos días compañeros, siempre he encontrado soluciones a casi todos los problemas en este grupo pero en esta ocasión, no encuentro el camino.

Les resumo mi situación, tengo dos tablas dbf, una tiene 180 mb y la otra 150 mb (aprox. 300.000 registros en una tabla y la otra 1 millón). Habitualmente uso filtros pero debido a la cantidad de registros que tienen ya resulta demasiado lento y estoy haciendo Query. Las consultas me salen bien, son rápidas y todo perfecto, pero el problema lo tengo cuando se modifican, eliminan o añaden registros a esa consulta. La pregunta es, ¿cómo actualizo sólo los registros de la tabla origen, tanto si elimino como si modifico o añado?

He pensado que al salir del formulario de la consulta, borrar de la tabla origen todos los registros del mes (el query es una consulta del mes en el que estoy) y añadir todos los registros de la consulta que he hecho pero no sé si es la mejor solución y sobre todo rápida y segura.

Gracias de antemano.

Carlos Miguel FARIAS

unread,
Feb 2, 2015, 7:27:11 AM2/2/15
to Grupo Fox
Evidentemente, con esa cantidad de registros, nunca accedes a todos, solo a un conjunto que dependerá de requerimientos (algo obvio, pero es parte del razonamiento).
Entiendo que accedes a tablas nativas, no puedo deducir que estés usando un SGBD externo.
Para hacer la consulta, estableces filtros sobre las tablas originales (no puedo deducir de tus indicaciones que uses algún tipo de cursor). Query=Consulta.
Primer paso (supongo que lo tienes resuelto porque dices que la consulta es rápida) es tener un índice sobre cada filtro.
Segundo: Armar un cursor de la consulta con SQL SELECT (si hay más de una tabla, es la única forma de que se active RUSHMORE).
Ese select debe enumerar todos y únicamente los campos que necesitas visualizar, e incluir las claves primarias de las tablas involucradas.
Una vez que tienes cargadas los registros nuevos, los modificados y marcados los a borrar, hacer un proceso tipo lote, al cerrar el formulario (con aviso al usuario para que no se desespere, por si tarda). Como tienes las claves primarias de los registros de las tablas, no tienes más que hacer un SEEK() y LOCK + UPDATE (REPLACE) o DELETE, y UNLOCK para cambios y borrados o un INSERT INTO ... SELECT ... nuevos registros.
En tablas DBF, el borrado es lógico (no físico), el físico deberá "limpiarse" fuera del horario "usuarios" del sistema y correr en horario con uso exclusivo.
Otra posibilidad es trabajar con Buffers activos.
Saludos: Miguel, La Pampa (RA)

integral

unread,
Feb 2, 2015, 9:21:50 AM2/2/15
to publice...@googlegroups.com

Amigo SERGIO :

Para Añadir y actualziar registros te recomiendo que utilices los siguientes comandos :

  INSERT INTO
  UPDATE  

El tema principal es tener la tabla origen ordenada mediante un  Select.. Order By o mediante el INDEX ON

PD : DEBERAN TENER EL MISMO CAMPO DE ORDENACION

Saludos,

INTEGRAL

Sergio Ps

unread,
Feb 2, 2015, 10:31:41 AM2/2/15
to publice...@googlegroups.com
Seguramente no me he expresado bien. Voy a intentar explicarlo lo más detalladamente posible:

Tengo 2 tablas libres DBF ordenadas por "mes+codigo". En la tabla "A" solo tengo un registro por cada "mes+codigo" y en la tabla "B" tengo varios registros por cada "mes+codigo". Imaginemos...

Tabla A                               Tabla B
Mes       Código                   Mes        Código     Concepto
01          00001                    01           00001                  1
01          00002                    01           00001                  2
                                          01           00001                  5
                                          01           00002                  3
                                          01           00002                  6

Genero una consulta de ambos ficheros: SELECT * FROM "A" WHERE mes="mes que quiero" INTO TABLE "SQL_A"
 y de la tabla "B": SELECT * FROM "B" WHERE mes="mes que quiero" INTO TABLE "SQL_B"

Después de crear estas consultas, cierro los ficheros originales y abro estas consultas con los alias de las tablas "A" y "B" para que la programación asociada a estas tablas siga siendo la misma y no tener que buscar nada más.
Como en estas tablas (las SQL que se han creado) se pueden añadir, eliminar o modificar registros, mi duda es cómo es la manera más eficaz de que esos cambios se realicen en las tablas originales "A" y "B" al salir del formulario.

Espero haberme explicado mejor y sino lo intentaré de otra manera.

Gracias de nuevo compañeros.

mapner

unread,
Feb 2, 2015, 10:46:30 AM2/2/15
to publice...@googlegroups.com
Para actualizar sobre consultas:
1) si en la consulta viene el id del registro, lo ubicas en la tabla original (en otra área) con seek , lo actualizas y listo.
2) accediendo vía ODBC como si fuera un motor externo y haciendo una vista remota actualizable.
3) haciendo un update de la tabla original y en el where usar la consulta
4) usa consulta y la tabla original relacionadas con SET RELATION TO (similar a opción 1)
5) ...

* saludos

Antonio Meza

unread,
Feb 2, 2015, 11:40:51 AM2/2/15
to publice...@googlegroups.com
Te recomiendo usar Vistas Locales, de esta forma puedes guardar los cambios que realices en los cursores devueltos por la vista como si fueran las propias DBF's.

saludos
Antonio Meza

Jose Mario

unread,
Feb 2, 2015, 12:23:29 PM2/2/15
to publice...@googlegroups.com
yo lo hago asi, cuando consulto, me llevo el numero registro de las tablas originales y lo agrego
junto con los cursores generados, que tu le llamas A y B

entonces
cuando paso por cada campo que no es llave, por ejemplo el numero de factura, no puedo modificar este, lo elimino, si 
lo que debes eliminar se puede,  contabilidad, por que las facturas debe quedar un constancia, del registro
si agrego marco estos que he agregado, con un campo, que me diga, los nuevos este campo les coloco
"A", append y cuando grabo, al original solo agrego los que este campo tienen A y los demas los modifico
con numero de registro

otra que me dijeron es si modificas el detalle
anular todos y luego volverlos agregar todos 
estamos hablando a la tabla original

no se me entiendes





El lunes, 2 de febrero de 2015, 9:31:41 (UTC-6), Sergio Ps escribió:

Sergio Ps

unread,
Feb 2, 2015, 1:08:00 PM2/2/15
to publice...@googlegroups.com
Ante todo, muchas gracias por las respuestas.

Es cierto que aunque el ejemplo es simple, las tablas "A" y "B" son muy grandes (alrededor de 50 campos cada una) y mediante muchas funciones en distintos "prg" los valores pueden cambiar por lo que me es bastante complicado verificar los cambios. De ahí que quiera usar el mismo alias que las tablas originales.

Me habéis comentado tanto mapner como Jose Mario incluir el número de registro del original, en estos casos, ¿cómo se haría el SELECT para incluir un campo con el RECNO()? ¿Qué hacéis en caso de que se elimine un registro en la consulta?
Antonio, el tema de las Vistas Locales ¿cómo funciona?, ¿me puedes dar alguna información?

Mi última opción quiero que sea eliminar todo lo filtrado en las tablas originales y añadir de las consultas por lo que pueda tardar y porque si en ese momento se va la luz... peligro aunque es lo más sencillo y efectivo.


El lunes, 2 de febrero de 2015, 10:18:47 (UTC+1), Sergio Ps escribió:

mapner

unread,
Feb 2, 2015, 2:05:11 PM2/2/15
to publice...@googlegroups.com
Sergio Ps,

Yo hice referencia al ID del registro, no al RECNO(), pero si, lo puedes incluir como expresión del SELECT de la consulta
 SELECT RECNO() as rec_no, campo... from ... INTO CURSOS Qry1

luego para ubicar en la tabla original

SELECT MiTablaOriginal
GOTO Qry1.rec_no
* acá actualizo y grabo

El tema de llevar dos cursores, uno para la consulta y otro para actualizar es que debes sincronizarlos para que los cambios se reflejen en ambos. 
Igualmente en un ambiente multiusuario la consulta no reflejará los cambios hechos por otros usuarios hasta que hagas la reinicialices.

Antonio Meza también recomendó Vistas Locales que es una forma de tener una consulta actualizable con DBF todo en uno. El único asunto es que debes crear una BD DBC de VFP como contenedor.

Saludos 

Mario Oviedo

unread,
Feb 2, 2015, 4:02:28 PM2/2/15
to publice...@googlegroups.com
lo tengo asi, consulta, modificar, eimina, adicionar, nuevo, grabar, limpiar, salir
si entras a consulta  no actuazas nada
si entras a modificar


este es valid del grid, text1

  SELECT temporal
  m.registro=temporal.registro

  SELECT movimi
  GO m.registro
  REPLACE NEXT 1 flag WITH this.Value IN movimi



 REPLACE NEXT 1 flag WITH this.Value IN temporal



si eliminar
lo coloco en dobleclic
  SELECT temporal
  m.registro=temporal.registro

  SELECT movimi
  GO m.registro
 dele te next 1

grabarr

sele temporal
COUNT to cuantos for tipom=" " and ! EMPTY(fecha) and ! EMPTY(descrip) and cargo+abono<>0 and ! deleted()
if cuantos=0
   messagebox("No hay registros que grabar",0+32+0,"Presione Enter")
   retur 0
endif


adicion y nuevo docume
IF opc=3 OR opc=4
DELETE FROM temporal WHERE EMPTY(fecha) OR EMPTY(descrip) OR cargo+abono=0

sele temporal
SET FILTER TO tipom=" "
SCAN
asigno las variable
luego hago el insert
sele temporal
endscan



panta.jpg

Sergio Ps

unread,
Feb 3, 2015, 11:51:57 AM2/3/15
to publice...@googlegroups.com
Jose Mario, me parece una buena idea a seguir pero supone un gran cambio interno en la Aplicación que por ahora no puedo.

mapner, la idea de incluir el Recno me seduce porque lo de la ID no sé a qué te refieres. Voy a intentar generarla en esta semana y si veo que me surgen dudas espero volver a teneros ahí.

Gracias y saludos.


El lunes, 2 de febrero de 2015, 10:18:47 (UTC+1), Sergio Ps escribió:

Mario Oviedo

unread,
Feb 4, 2015, 8:55:02 AM2/4/15
to publice...@googlegroups.com
el ID es una llave por ejemplo 
clase de documento
ventas contado "01"
ventas credito  "02"
nota de credito "03
nota de debito  "04"
asi sucesivamente
mas el numero de documento

id documento  +   numero de documento  
es una llave que tenes que indexa
010000001000
index on id+nfactura tag factura

mas o menos 





Sergio Ps

unread,
Feb 5, 2015, 11:20:05 AM2/5/15
to publice...@googlegroups.com
Gracias Jose Mario, te refieres a la indexación en sí.


El lunes, 2 de febrero de 2015, 10:18:47 (UTC+1), Sergio Ps escribió:

Mario Oviedo

unread,
Feb 5, 2015, 12:34:00 PM2/5/15
to publice...@googlegroups.com
claro una identificacion unica en el documento, que en encabezado no se duplique, solo en sus detalles, que identique las demas facturas, hablando de facturas, en algunos casos en autoincrmental automatico de fox y de motores, depende de gustos
Reply all
Reply to author
Forward
0 new messages