LOCATE FOR A SQL LIKE

954 views
Skip to first unread message

contabil...@gmail.com

unread,
Oct 4, 2015, 10:18:47 PM10/4/15
to Mundo Visual FoxPro
Buenas noches,

cual puede ser la mejor manera de cambiar comandos como locate for o seek por otros mas enfocados a sql como like, ustedes en su experiencia que recomiendan?


desde ya muchas gracias por sus opiniones

saludos,

Ben


HernanCano

unread,
Oct 5, 2015, 3:29:40 AM10/5/15
to Mundo Visual FoxPro
No existen.

Tanto los comandos LOCATE como SEEK se aplican sobre datos nativos en VFP y lenguajes similares, donde ambos posicionan el "puntero" sobre un registro (que cumpla con la condición).

Pero en el lenguaje SQL (tanto aplicado a datos nativos --archivos DBF-- como a datos remotos --motores de bases de datos externos--) se deben "pedir" datos al motor y el motor te "devuelve" un conjunto de registros, no te indica si se "posicionó" en algún registro en particular. Esto de "posicionarse en algún registro" no es tema de los motores de bases de datos externos.

El chip cambia.

Carlos Miguel FARIAS

unread,
Oct 5, 2015, 9:01:51 AM10/5/15
to mundovisualfoxpro
Tal como indica Hernan, el enfoque es diferente.
Primero, toda la operatoria natural del xBASE, está orientada en principio a Registro.
Primero prima, toda operatoria natural del SQL, está orientada a conjunto de registros.

Un LOCATE te ubica (o no) un registro que cumpla con las condiciones indicadas.
En un LOCATE, para recuperar el siguiente registro que cumpla la misma condición, debes hacer un CONTINUE

Un SEEK te ubica (o no) un registro que tenga un valor de clave igual al indicado.
En un SEEK, si encuetra el registro, se "posiciona sobre él", y si no, dependera del SET NEAR (te deja al final del archivo o cerca en el registro con la clave más parecida).

Para reemplazar un LOCATE con SQL, debes usar SELECT.
Un select con condiciones (WHERE) que no son sobre campos claves o que indican rangos, reemplaza al LOCATE + CONTINUE.
O sea que te crea un cursor con todos los registros que cumple con el LOCATE (en este caso, dentro del WHERE).

Para reemplazar un SEEK con SQL, debes usar SELECT.
Un select que en el WHERE pregunta por un valor comparado contra una clave primaria, te estaría devolviendo un CURSOR de un solo registro.

Lo indicado responde a cuando uso LOCATE o SEEK para leer datos.

Con SELECT, tienes como ventaja sobre LOCATE o SEEK, es que puedes traer registros de varias tablas y crear tu propio "paquete" (cursor) para trabajar, eso lo haces relacionando adecuadamente las tablas necesarias en la clausula FROM

Pero, si lo que se quiere es reemplazar (buscar y reemplazar)
Lo más simple es usar el comando UPDATE (con cuidado).

El UPDATE reemplazará datos de todos los registros que cumplan con las condiciones que se indican en el WHERE.
Si la condición iguala valor a clave primaria, modifica un registro, caso contrario, modifica varios.

El UPDATE es más potente que el REPLACE (con clausula FOR), por que en el FOR del REPLACE solo puedes hacer mención a datos en los registros de la tabla sobre la que estás trabajando o datos ya recuperados en otras tablas, previas.

En UPDATE, sobre todo en SQL de vfp9, o MSSQL Server, mysql, postgresql, puedes estar recuperando datos de otras tablas al momento de la modificación.

UPDATE Totales SET total1 = (SELECT SUM(campo1) FROM unaTabla WHERE blabla),;
   total2 = (SELECT SUM(otrocampo1) FROM otraTabla WHERE otroblabla) WHERE reblabla

El SQL es un lenguaje que describe como se opera sobre los registros (recupero, actualización o borrado).
Ten en cuenta que intentará afectar todos los registros que cumplan con las condiciones del WHERE, para evitar sorpresas, antes de armar UPDATE o DELETE de SQL, chequea que traiga lo correcto con un SELECT y las mismas condiciones WHERE que piensas aplicar a UPDATEs y DELETEs.

Y lo más importante del cambio de Chip, es que con SQL, tu lógica de manejo de datos es un 90% compatible con cualquier SGBD, y eso hace que si toda la lógica de datos la transportas a SQL, tienes transportada tu lógica de datos a cualquier plataforma de desarrollo (VFP, C++, C#, Python, PHP, etc.) en un 90%.

Sugiero Aplique SQL de Groff, excelente libro sobre SQL práctico, aplicado.

Saludos: Miguel, La Pampa (RA)

Larga Vida y Prosperidad
Que la Fuerza los acompañe si no tienen SQL


--
_______________________________________________________________
Has recibido este mensaje porque estás suscrito al Grupo "Mundo Visual
FoxPro" de Grupos de Google.
 
Para anular la suscripción a este grupo, envía un mensaje a:
mundovisualfox...@googlegroups.com
---
Has recibido este mensaje porque estás suscrito al grupo "Mundo Visual FoxPro" de Grupos de Google.
Para anular la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a mundovisualfox...@googlegroups.com.
Para acceder a más opciones, visita https://groups.google.com/d/optout.

contabil...@gmail.com

unread,
Oct 6, 2015, 3:38:26 PM10/6/15
to Mundo Visual FoxPro
Muchas gracias Hernan y Miguel, por tan ilustrada explicación

saludos,

Oscar b

unread,
Oct 23, 2015, 11:26:06 AM10/23/15
to mundovis...@googlegroups.com

Utiliza consultas basadas en el standard de SQL te recomiendo xq en un futuro si deseas migrar a otro motor el cambio seria muy minimo.

Carlos Miguel FARIAS

unread,
Oct 23, 2015, 11:32:13 AM10/23/15
to mundovisualfoxpro
Casi 20 días de atraso. Y ya se había dado esa sugerencia.
Que Pasa Oscar?, no encontrabas el abrecartas?

Saludos: Miguel, La Pampa (RA)

Larga Vida y Prosperidad
Que la Fuerza los acompañe.

mhlezama

unread,
May 3, 2017, 1:31:02 PM5/3/17
to Mundo Visual FoxPro
Saludos Hernan

Si SELECT te devuelve datos y no posición, como puedo saber si encontró datos???

En visual lo hacemos así

SEEK buscardatos
IF FOUND()

ELSE

ENDIF



Cómo se hace en MYSQL, Como logró saber que obtuve datos y que no esta vacio?????

Carlos Miguel FARIAS

unread,
May 3, 2017, 3:24:05 PM5/3/17
to mundovisualfoxpro
Si piensas que puedes solucionar la lógica de acceso a datos a un SGBD no nativo programando en fox antiguo va a ser difícil que puedas solucionarlo.
Con las instrucciones que tu indicas te falta.
Seleccionar el área donde vas a hacer el SEEK, eso implica, que deberías volver luego al área previa.
Debes activar el indice sobre el que haces el seek (debes luego restaurar cualquier otro indice previo, o a ninguno, si no lo había), esa activación de índice puede crear conflicto cualquier SQL posterior.
En cambio con un simple
IF SEEK(Clave, tabla, indice) solucionas el problema  (y no tienes que usar found).

Si usas SQL sobre tablas nativas, sabes o no si recuperastes o afectastes datos con la variable pública _TALLY, que indica cuantos registros leistes, borrastes o actualizastes.

En mysql hay funciones que te devuelven la cantidad de registros recuperados de una consulta, es cuestión de investigar.

En vfp, si usas SQL passthru, con SQLEXEC(nStatementHandle [, cSQLCommand [, cCursorName[, aCountInfo]]]) el último parámetro te indica cuantos registros se tocaron. Si es un select, además con reccount() sobre el cursor retornado tenes cuantos registros accedió.

Por lo tanto, con investigar un poco, se puede obtener la información que se necesita, pero repito, la lógica de acceso a datos usando solo SQL es diferente a la de usar comandos nativos para acceder a los datos.

Los comandos nativos podrás seguir usandolos sobre cursores recuperados.

No es recomendable usar vistas remotas para otra cosa que no sea recuperar datos.
Saludos: Miguel, La Pampa (RA)
Larga Vida y Prosperidad
Que la Fuerza los acompañe


--
_______________________________________________________________
Has recibido este mensaje porque estás suscrito al Grupo "Mundo Visual
FoxPro" de Grupos de Google.
 
Para anular la suscripción a este grupo, envía un mensaje a:

---
Has recibido este mensaje porque estás suscrito al grupo "Mundo Visual FoxPro" de Grupos de Google.
Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a mundovisualfoxpro+unsubscribe@googlegroups.com.

Jorge González

unread,
May 3, 2017, 7:56:13 PM5/3/17
to Mundo Visual FoxPro
Hola Contabil
Tal como te indica Hernan. Debes estudiar acerca de consultas o filtros basados en SQL. En  Fox son potentes y en otros motores de base de datos varían en muy pocas cosas o detalles
Consulta el help o la ayuda del Visual Foxpro y en la linea buscar escribes: Select -SQL y lee detenidamente la explicación y practicalo con cualquier tabla
Consulta los principales comandos SQL como lo son:
insert-sql
update-sql
delete-sql

Con una sentencia SQL limitando la respuesta a solo lo que te interesa obtener por medio de la clausula Where... no te hará falta usar el comando LOCATE o el anticuado SEEK, a menos que la respuesta obtenida sean varios registros pero aún así, no se usa por razonamiento del alcance de la sentencia SQL. Es decir, siempre se obtiene lo que se quiere.
Las sintaxis son similares. Si estás acostumbrado a la programación visual o por medio de asistentes crea consultas por medio del diseñador de consultas pero solo con la intención de que veas el código SQL generado por el mismo, de esa manera cubrirás muchas dudas.

Aprende sobre create cursor ya que son una poderosa herramienta de VFP para presentar o manipular datos obtenidos por medio de una consulta.

Y para responder tu pregunta sobre si se obtuvo datos o no usa el comando RECCOUNT()

Te doy un ejemplo con una tabla nativa

TexBox.Valid   && Este sería el valid del textbox donde el usuario introduce el código a consultar
  Local pnRegistro
  pnRegistro=SolicitaExistenciaCodigoCliente(This.value)
  IF pnRegistro<1
     WAIT WIND 'El código introducido no se encontró en tabla de clientes'
  ELSE
     SolicitaDatosDelCliente(This.Value)
  ENDIF


Procedure SolicitaExistenciaCodigoCliente(cCodigoAConsultar)
  LOCAL nCantidadRegistro 
  USE TablaCliente IN 20 
  SELECT TablaCliente.codigo_cliente FROM TablaCliente WHERE TablaCliente.codigo_cliente= cCodigoAConsultar;
  INTO CURSOR qClientes
  nCantidadRegistro = RECCOUNT()  &&   Lee Explicacion 1 mas abajo
  USE IN SELECT('qClientes')
  USE IN SELECT('TablaCliente')
  RETURN nCantidadRegistro
ENDPROC

Explicación 1: Si consultas la sintaxis de la función RECCOUNT() te darás cuenta que devuelve la cantidad de registros contenidos de la tabla a quien se consulta y a esta función hay que pasarle como parametro el nombre de la tabla o cursor a consultar entre guiones dobles o simples, pero cuando se hace una consulta SQL, VFP deja activa la sesión o el área donde se creo el cursor resultante de la consulta. En este caso qClientes. La sintaxis correcta sería: RECCOUNT('qClientes') pero como inmediatamente después de hacer la consulta SQL se usa la función RECCOUNT(), el nombre es tácito, no hace falta

Es importante recalcar que la función definida por el usuario "SolicitaExistenciaCodigoCliente()" tiene como fin unicamente hacer saber si el código existe o no.
Las funciones deben ser específicas y no se aconseja programar super funciones que hacen varias tareas porque es casi seguro que parte de ese algoritmo lo volvamos a necesitar y en vez de rehusar un algoritmo, se comete el siempre error de volverlo a escribir en otra función definida por el usuario

Otra observación muy importante   
Si estás acostumbrado a la programación por asistentes o programación visual o gráfica, te recomiendo que te plantees un mayor dominio del uso manual de los comandos, y sería una buena idea usar esta ocación de aprendizaje SQL de esa manera.
Es una opinión personal aunque los programadores amantes del código estructurado y que quieren tener un dominio total de un proyecto de seguro estarán de acuerdo conmino.

Por lo pronto, estudia detenidamente los comandos SQL que te coloqué arriba y que los colaboradores ya te habían mencionado. Puedes escribir el código de la función directamente en el valid a manera de practicar y ver las respuestas obtenidas.Puedes pasarnos por aqui las líneas de código que escribes y te seguiremos ayudando


Ben


HernanCano

unread,
May 4, 2017, 9:52:16 PM5/4/17
to Mundo Visual FoxPro

La sintaxis desde VFP para ejecutar un comando en lenguaje SQL hacia un motor de bases de datos es más o menos así:

SQLEXEC ( M.nConexion, "select * from CLIENTES where CODIGO='"+M.xCod+"' ", 'csrCLIENTES')

lo que nos indica que estás generando un cursor llamado csrCLIENTES con los datos que la consulta te entregue.

Como csrCLIENTES es un cursor de VFP, para saber si tiene datos lo que haces es preguntarle si tiene registros, más o menos así:

if reccount('csrCLIENTES')=0
   =MessageBox('No se encontraron datos')
else
   =MessageBox('Sí se encontraron datos')
   browse
   report form ELREPORTE preview
endif

Házlo y nos cuentas.


El miércoles, 3 de mayo de 2017, 12:31:02 (UTC-5), mhlezama escribió:
Saludos Hernan
Reply all
Reply to author
Forward
0 new messages