Re: Seek() ó SELECT SQL??

583 views
Skip to first unread message
Message has been deleted

Antonio Meza

unread,
Jun 22, 2015, 8:36:16 PM6/22/15
to publice...@googlegroups.com, vfxpro...@gmail.com
Hola Saul !!

La respuesta sencilla es usar Select siempre!!

Sin embargo creo que necesitas entender algo muy importante, en cualquier servidor de base de datos relacional ejemplo Mysql, SqlServer, Oracle, MariaDb, etc, etc, solo debes traer en la consulta el o los registros que necesitas, es una mala practica traer todos los registros (salvo realmente se requiera) pero para este caso que es para buscar uno o algunos registros lo puedes hacer directamente en la consulta y no traer todos los registros para luego aplicar un locate porque el Seek trabaja con indices y las consultas a un servidor no te generan indices los tendrías que hacer manual ya con el cursor devuelto, lo que es trabajar de mas para algo que un simple Select te soluciona.

Este es uno de los detalles por lo que a muchos se les dificulta usar FoxyDb o cambiarse a un Servidor de base de datos, ya que la costumbre de tener toda la tabla a disposición (dbf) y en Cliente Servidor solo debes usar el o los registros necesarios cuesta mucho entender esto.

De todas formas lo puedes hacer, es decir traerte toda la tabla y luego crearle un indice al cursor y utilizar Seek() o Locate, es una mala practica traer todos los registros, y luego terminas haciendo un montón de cosas que no son necesarias si aplicas buenas practicas.

saludos
Antonio Meza



El lunes, 22 de junio de 2015, 19:08:49 (UTC-5), Saul Piña Hernandez escribió:
Saludos, ante de que me digan que lea en la ayuda, ya lo hice, pero aun así tengo una curiosidad, digamos que quiero tratar de ya no utilizar los comando nativos de VFP y en lugar de ellos utilizar y adecuar mi codigo a motor de base de datos, es por ello y pensando en que mi escenario es MySQL (por decir un ejemplo). y para la tarea de buscar un registro en una tabla mySQL que es mas recomendable?

Función Seek()   ó
Select mi_campo from mi_tabla??

gracias.



Víctor Hugo Espínola Domínguez

unread,
Jun 22, 2015, 8:55:54 PM6/22/15
to publice...@googlegroups.com
Hola Saúl

> digamos que quiero tratar de ya no utilizar los comando nativos de VFP y en lugar de ellos utilizar y adecuar mi codigo a motor de base >de datos, es por ello y pensando en que ...

No es el código lo que debes adecuar sino el DISEÑO de tus aplicaciones, el ´código de acceso a datos solo se escribe en la capa de datos, en raras ocasiones quizás necesites manipular cursores en las otras capas y ahí puedes usar las instrucciones nativas de Foxpro que más te gusten.


Para el diseño en capas no tiene importancia que tus datos sean nativos o externos, puedes bajar un ejemplo desde: http://www.mediafire.com/download/hbmr0r5u7z5ysur/EjemploABM3Kpas.rar

>mi escenario es MySQL (por decir un ejemplo). y para la tarea de buscar un registro en una tabla mySQL que es mas recomendable?
>
>Función Seek()   ó
>Select mi_campo from mi_tabla??

Para buscar un registro en una tabla de MySql o Sql Server o Firebird o cualquier motor de base de datos diferente a Foxpro NO puedes usar SEEK ni LOCATE, porque sencillamente esos comandos no existen!

Saludos,
Víctor.
Lambaré - Paraguay.

Carlos Miguel FARIAS

unread,
Jun 23, 2015, 8:39:48 AM6/23/15
to Grupo Fox
Para cualquier motor de bd (inclusive dbf) un SELECT de SQL incorporando en el WHERE la clave primaria de la tabla a acceder es equivalente a un SEEK.
Posiblemente, un SEEK sea más efectivo que un SELECT en DBFs (no existe en otros motores), más que nada, porque luego para actualizar los datos, se puede hacer un REPLACE sin condiciones y si usamos un SELECT, luego debemos hacer un UPDATE con la misma condición en el WHERE que pusimos en el SELECT.
Que aplicaría:
Evidentemente para DBFs, es más simple usar un SEEK (la función), con todos sus parámetros (valor busqueda, nombre tabla, nombre índice) ya que eso, lo puedo meter un if y controlo el flujo lógico directamente.
Pero...

Supongamos que se requiere acceder a un registro y modificarlo, si la tabla esta abierta, dejarla abierta en el orden de indice que estaba, y si no dejarla cerrada. En todos los casos, dejar la tabla en uso al momento del proceso, seleccionada (o sea un entorno de trabajo limpio y aislado, lo hecho no afecta el entorno de otros programas procedimientos)

Comparemos:
* Código a lo dbase III
tablaPrevia = SELECT(0)
IF USED(unaTabla)
   indicePrevio = ORDER()
   SELECT unaTabla
   abierta = .T.
ELSE
   SELECT 0
   USE unaTabla
   indicePrevio = 0
   abierta = .F.
ENDIF
SET INDEX TO ORDER 1
SEEK cClaveBusco
IF FOUND()
   * Aca hago calculos o lo que tengo que hacer si lo encuentro
   REPLACE campoReemplazo WITH datoReemplazo
ELSE
   WAIT WINDOW "Registro No Esta"
ENDIF
IF abierta  && Si estaba abierta, la dejo en el orden previo
   SET ORDER TO indicePrevio
ELSE
   USE
ENDIF
SELECT (tablaPrevia)
* Código muestra, puede faltar algún paréntesis o algín detalle
* 25 líneas de código

ya con fox (optimizado?)
* Código tipo Fox
cerrada = NOT USED(unaTabla)
IF cerrada
   USE unaTabla IN 0
ENDIF
IF SEEK(cClaveBusco, 'unaTabla', 'elIndice')
   * Aca hago lo que tengo que hacer si lo encuentro
   REPLACE unaTabla.campoReemplazo WITH datoReemplazo
ELSE
   WAIT WINDOW "Registro No Esta"
ENDIF
IF cerrada
   USE IN unaTabla
ENDIF
* Como no seleccione el área de la tabla, accedo sus datos calificando los campos, no necesito volver a
* seleccionar la tabla que estaba en uso antes de entrar (menos instrucciones).
* Como la tabla, si abierta, no lo modifico el indice en uso, no tengo luego que restaurarlo.
* 14 líneas de código

y usando SELECT de SQL
* Código Fox usando SQL
cerrada = NOT USED(unaTabla)
IF cerrada
   USE unaTabla IN 0
ENDIF
SELECT solo, Datos, Necesito FROM unaTabla INTO CURSOR acaTrabajo WHERE campoPrimario=cClaveBusco
IF _TALLY>0
   * Aca hago lo que tengo que hacer si lo encuentro
   UPDATE unaTabla SET campoReemplazo = datoReemplazo WHERE campoPrimario=cClaveBusco
ELSE
   WAIT WINDOW "Registro No Esta"
ENDIF
IF cerrada
   USE IN unaTabla
ENDIF
* Como no seleccione el área de la tabla, accedo sus datos calificando los campos, no necesito volver a
* seleccionar la tabla que estaba en uso antes de entrar (menos instrucciones) (igual quen "buen" fox).
* No me tengo que preocupar si hay indices creados o no, igual funciona, el indice mejora el desempeño
* 14 líneas de código

y usando UPDATE directamente (en casos especiales donde el calculo de datoReemplazo lo puedo hacer con una función
* Código Fox usando SQL
cerrada = NOT USED(unaTabla)
IF cerrada
   USE unaTabla IN 0
ENDIF
UPDATE unaTabla SET campoReemplazo = <funcion para calcular datoReemplazo) WHERE campoPrimario = cClaveBusco
IF _TALLY == 0
   WAIT WINDOW "Registro No Esta"
ENDIF
IF cerrada
   USE IN unaTabla
ENDIF
* Como no seleccione el área de la tabla, accedo sus datos calificando los campos, no necesito volver a
* seleccionar la tabla que estaba en uso antes de entrar (menos instrucciones) (igual quen "buen" fox).
* No me tengo que preocupar si hay indices creados o no, igual funciona, el indice mejora el desempeño
* Hay que tener en cuenta que en el UPDATE, tengo disponibles todos los datos del registro de la tabla
* sobre el que hago el remplazo (lo que en el caso anterior denomine "Solo, Datos, Necesito")
* 11 líneas de código

O sea, que en fox, usando SQL, el código puede lograrse soluciones aún más simples que fox puro y no que decir, del uso de fox a lo xbase, que he visto en muchos ejemplos que suelen postearse en foros sobre fox.
saludos: Miguel, La Pampa (RA)
Reply all
Reply to author
Forward
0 new messages