SELECT SQL y RECNO()

678 views
Skip to first unread message

PabloZa

unread,
Aug 20, 2012, 8:22:56 AM8/20/12
to publice...@googlegroups.com
Hola gente del Foro. Me surgio un problemita
Tengo una tabla ARTICULOS.DBF con información de stock.
Estoy haciendo un proceso para cambiar el precio de un grupo de esos artículos de acuerdo al código de proveedor. para ello genero desde una línea de SQL un cursor, lo muestro, modifico los precios en el cursor, etc.
ahora viene mi pregunta: cuando quiero pasar esas modificaciones a la tabla ARTICULOS.DBF para que queden en forma definitiva,
cual es la mejor manera de hacerlo? porque en el cursor no tengo el Numero de registro de cada uno de los artículos que extraje de ARTICULOS.DBF.
Saludos

GeoSys Diseño de Software

unread,
Aug 20, 2012, 9:24:24 AM8/20/12
to publice...@googlegroups.com
Pabloza, puedes guiarte por el código de artículo, me imagino que no se repiten los códigos por supuesto.


Saludos

Anthony Contreras Peralta

Costa Rica.




--
 
 
 

mpulla

unread,
Aug 20, 2012, 9:37:23 AM8/20/12
to publice...@googlegroups.com
Hola Pablo

Cada tabla debe tener una llave que identifica de manera única a los registros y no debiría ser el número de registro.

Puedes hacerlo por
1.- buffering (creas un nuevo form con  buffermode  = 5, en el enviroment del form abres la tabla, creas una grilla vinculas la tabla readonly para los campos que no quieras modificar, en un commanbutton haces un tablepudate())
2.- CursorAdapter
3.- Update Articulo Set precio = Precio + 20 where Proveedor = 123

Saludos.
Mauricio

FidelJ

unread,
Aug 20, 2012, 10:07:31 AM8/20/12
to publice...@googlegroups.com
Podés tener el número de registro de manera muy fácil
select *,recno() from articulos into cursor NombreCursor
Esto agrega una última columna llamada "Exp_n", donde n coincide con el número de campo. Por lo que para saber cual es el nombre del campo, solamente tenés que hacer
lcExp="Exp_"+ltrim(str(fcount( "NombreCursor" ) ) )
LnRegistro=Evaluate(lcExp) && devuelve el número de registro de la tabla original.
select articulos
go lnRegistro
if rlock()
   * reemplazo de valores
 UNLOCK
ENDIF

Guillermo MDQ

unread,
Aug 20, 2012, 10:32:29 AM8/20/12
to publice...@googlegroups.com
Pablo, ya que preguntaste cual es la mejor forma de hacerlo, pues la mejor forma es no usar RECNO().
La forma correcta es tener una clave primaria que identifica de manera unica cada registro, que en el caso de tu tabla de articulos puede ser el numero de articulo, que se supone no se repite. Y sino puedes utilizar un campo especifico para utilizarlo como clave.
No importa si insertas o eliminas registros la clave primaria nunca va a cambiar para su registro correspondiente.
Y te sirve para actualizar de cualquier forma que utilices como te indico el colega mpulla.

Saludos
Guillermo

Fox Learner

unread,
Aug 20, 2012, 10:50:13 AM8/20/12
to publice...@googlegroups.com
La Clave Primaria solo funcionará si estas usando base de datos nativa. Si estas usando tablas libres, éstas aceptan duplicados y por lo tanto tendrías que buscar una forma única de identificar los registros..

Saludos!

mpulla

unread,
Aug 20, 2012, 11:09:53 AM8/20/12
to publice...@googlegroups.com
Hola Fox Learner.

Al trabajar con tablas libres puedes crear indices candidatos los cuales no te adminte valores duplicados.

Saludos.
Mauricio

Fox Learner

unread,
Aug 20, 2012, 11:36:58 AM8/20/12
to publice...@googlegroups.com
Gracias Mauricio, Me sirve saber que los indices candidatos NO aceptan duplicados.

Sin embargo, el manual parece indicar que un campo de una tabla libre, aun cuando tenga un indice candidato no se convertirá nunca en una Primary Key como tal, a lo cual me referí en mi comentario anterior cuando dije "Clave Primaria".

Solo lo aclaro para no confundir al compañero (porque es facil tener un error de conceptualización y confundir los términos), pero lo que tu mencionas sobre los índices candidatos sería la solución para NO tener datos duplicados, usando tablas libres.

Saludos!

Fox Learner

unread,
Aug 20, 2012, 11:42:24 AM8/20/12
to publice...@googlegroups.com
En mi caso, puesto que uso mucho las tablas libres, siempre hago una validación de forma explícita antes de intentar ingresar datos a una tabla.

Boton Agregar:

Antes de grabar, realiza una busqueda del dato que no debe duplicarse.
Si lo encuentra, envia un mensaje de error al usuario.
Si no, graba el registro.

Saludos!

Carlos Miguel FARIAS

unread,
Aug 20, 2012, 5:06:24 PM8/20/12
to publice...@googlegroups.com
Los indices candidatos son permitidos en tablas libres? hum.
Los indices UNIQUE de libres permiten claves duplicadas pero solo indexan el primer registro que encuentran.
Se puede acceder sin problemas por número de registro, porque el archivo de datos /dbf) de vfp es plano, los nuevos se agregan siempre al final.
Ese número de registro solo es aplicable mientras no se haga un pack de la tabla, por lo que a partir de ese momento, los registros cambian su número (tienden al #1).
Es una metodología no recomendable, salvo para sistemas donde la velocidad de acceso sea crucial (y al azar) y entonces es si el método más rápido (no hacer pack, NO HACER PACK, PACK NOOOO!!!).
Eso solo sirve con tablas nativas. En otros SGBD no es aplicable.
Saludos: Miguel, La Pampa (RA)


--
 
 
 

HernanCano

unread,
Aug 20, 2012, 8:02:37 PM8/20/12
to publice...@googlegroups.com
PabloZa:
Si tienes el "número de registro" puedes usarlo según parece que piensas hacerlo. Si no lo tienes, no tienes impedimento para hacerlo: te basas en el códigodel artículo mientras sea un campo único en el archivo, es decir no tiene duplicados, no se repite... ¿éso es correcto? No lo mencionas, pero es que sin buenos datos es difícil explicarte algo (mira los comentarios referentes a íncices primerios y cardidatos).

Podrías hacer algo como:

select TEMPORAL
scan
update MAESTRODEARTICULOS set PRECIO = TEMPORAL.PRECIO where alltrim(MAESTRODEARTICULOS.CODIGO) == alltrim(TEMPORAL.CODIGO)
endscan

De esta forma es que te lo indica Anthony.

Mauricio, Miguel:
Desviaron el tema.

HernanCano

unread,
Aug 20, 2012, 8:15:56 PM8/20/12
to publice...@googlegroups.com

Miguel:


>> Los indices candidatos son permitidos en tablas libres? hum.

Estás haciendo una pregunta; la respuesta es: Sí.


>> Los indices UNIQUE de libres permiten claves duplicadas pero solo indexan el primer registro que encuentran.

Estás haciendo una afirmación; mi réplica es: Sí.


>> Se puede acceder sin problemas por número de registro, porque el archivo de datos /dbf) de vfp es plano, los nuevos se agregan siempre al final.

....: Sí.


>> Ese número de registro solo es aplicable mientras no se haga un pack de la tabla, por lo que a partir de ese momento, los registros cambian su número (tienden al #1).

....: Después de ejecutar PACK, los números de registro --posteriores a cada registro marcado para borrar-- cambian: Sí.

¿Qué quieres decir cuando mencionas "(tienden al #1)"?


>>Es una metodología no recomendable, salvo para sistemas donde la velocidad de acceso sea crucial (y al azar) y   entonces es si el método más rápido (no hacer pack, NO HACER PACK, PACK NOOOO!!!).

Se recomienda no hacer pack cada que se "borra" un registro (cada que se marca con DELETE). Esta recomendación no es por que cambien los números de registro, sino porque en entornos multiusuario y de red no es práctico y básicamente imposible de ejecutar (use MAESTRO exclusive, PACK), ya que otros usuarios estarán ejecutando la app y estarán usando el archivo que pretendo abrir de forma exclusiva para poder hacer PACK. Una tarea PACK se debe ejecutar en un momento en que nadie esté ejecutando la app. (¿Es necesario decir ésto cada que alguien pregunta al respecto?)


>> Eso solo sirve con tablas nativas. En otros SGBD no es aplicable.

...: Sí, es evidente. De todas formas no es el tema que se pregunta.

Walter R. Ojeda Valiente

unread,
Aug 20, 2012, 8:41:09 PM8/20/12
to publice...@googlegroups.com
El problema del PACK no es tanto que el archivo deba abrirse en forma exclusiva para ejecutarlo sino que en caso de ejecutarlo muchos registros se perderán para siempre .... y de acuerdo a la Ley de Murphy luego de hacer el PACK se descubrirá que dichos registros eran necesarios.

Por lo tanto, lo recomendable es NUNCA usar el PACK en tablas .DBF y hacerlo solamente con los cursores.

Claro que si eres muy cuidadoso podrías usarlo pero .... más vale prevenir.

Saludos.

Walter.





Date: Mon, 20 Aug 2012 17:15:56 -0700
From: jherna...@gmail.com
To: publice...@googlegroups.com
Subject: Re: [vfp] Re: SELECT SQL y RECNO()
--
 
 
 

Carlos Miguel FARIAS

unread,
Aug 21, 2012, 7:17:57 AM8/21/12
to publice...@googlegroups.com
Perdon no desvie el tema, la pregunta es sobre select y recno(), entonces, explico (al menos intento) los problemas de utilizar el número de registro para acceder y modificar registros usando esa alternativa.
Que significa que tiende a uno? Justo después de preguntarmelo, vos mismo lo respondes.
Por si otro no lo entendio.
a) Los registros tienen un número de registro físico que van de 1 a N.
b) Cuando se borra un registro k (y se hace pack), todos los registros posteriores a k pasan a tener un #registro menor.
c) Como k puede variar entre 1 y N, todos los registros van tendiendo su número a 1 (con cada Pack).

A veces las respuestas tienen que reorientar el problema, porque a veces el enfoque inicial de quien hace la pregunta está tan errado que hay que empezar de nuevo.

Como indique previamente, usar recno dentro de un select para luego usarlo para modificar registros es contraindicado. Que puede hacerse, si, que convenga NOO!!!
Y si no, tomate un ascensor para ir al Norte.

Saludos: Miguel, La Pampa (RA)

--
 
 
 

Guillermo MDQ

unread,
Aug 21, 2012, 9:47:03 AM8/21/12
to publice...@googlegroups.com
El compañero Pablo preguntó lo siguiente:

 ... cuando quiero pasar esas modificaciones a la tabla ARTICULOS.DBF para que queden en forma definitiva, cual es la mejor manera de hacerlo?

Asi que lo que debemos decirle es que usar recno() no es precisamente la mejor manera. Utilizar claves primarias es la mejor.

Saludos
Guillermo

Mario Oviedo

unread,
Sep 10, 2012, 4:15:32 PM9/10/12
to publice...@googlegroups.com
coloca un ejemplo de cursor adapter
por favor


--
 
 
 

Reply all
Reply to author
Forward
0 new messages