Problemas indice

Problemas indice

Postby diegopolverelli » Fri Nov 28, 2008 1:04 pm

Hola. Tengo una aplicacion que usa un indice que se compone de 3 campos caracter de 5, 16 y 10 de largo cada uno. Antes utilizaba un
locate e igualaba cada campo de la base con una variable; ahora hago un indice, y busco las 3 variables concatenadas.

El problema es que a veces, con el indice, se producen errores; no me encuentra un registro que existe, y me genera un duplicado (si no encuentra, lo da de alta). Probe muchisimas variantes de carga (muchos items, un solo item, etc.) pero en principio funciona bien con el locate y con el indice, pero cuando pongo el programa en produccion, la version con indice, una de 15 falla, y el del locate no.

Obviamente tengo funcionando el del locate, pero como se imaginaran, la performance del mismo, especialmente cuando trabajo en red, es peor.

¿se les ocurre que puede estar pasando? el indice esta armado de manera correcta; la prueba está en que funciona bien en muchas oportunidades. En fin, espero me puedan orientar. Ya no se por donde buscar. Gracias. Atte.
diegopolverelli
 
Posts: 149
Joined: Thu Jun 21, 2007 3:26 pm

Postby karinha » Fri Nov 28, 2008 2:01 pm

Muestra algo en la pratica, porfa.

Saludos.
João Santos - São Paulo - Brasil - Phone: +55(11)95150-7341
User avatar
karinha
 
Posts: 7416
Joined: Tue Dec 20, 2005 7:36 pm
Location: São Paulo - Brasil

ejemplo

Postby diegopolverelli » Fri Nov 28, 2008 2:37 pm

tengo una tabla st_stock indexada por
deposito+st_codigoart+st_lote (en in indice permamente)

hago un movimiento, tengo 10 productos que salen de stock:

hago un while, y segun el producto, lote y deposito de donde salen,
busco en la tabla st_stock y resto o sumo en un campo CANTIDAD. Si no esta el registro, agrego en st_stock un registro nuevo.
Si esa busqueda la hago asi:
loca for st_stock->coddep=xcoddep .and. st_stock->art_codig=xart_codig .and. st_stock->lote=xlote, y pongo el programa en produccion, funciona todo de 10... ahora, si uso el indice del cual hablo en los primeros renglones, tambien funciona bien, pero no siempre... a veces no me encuentra un registro que existe, y por ende, al agregar, me duplica un registro.

Es rarisimo. Trabajo en red contra un server, con fwh 803... en fin Gracias...!!!
diegopolverelli
 
Posts: 149
Joined: Thu Jun 21, 2007 3:26 pm

Postby karinha » Fri Nov 28, 2008 3:16 pm

Porque usas LOCATE en vez de DBSEEK()??

al agregar, me duplica un registro.

Esto és en una ALTERACION? Trabas el registro antes con RLOCK()?


Saludos.
João Santos - São Paulo - Brasil - Phone: +55(11)95150-7341
User avatar
karinha
 
Posts: 7416
Joined: Tue Dec 20, 2005 7:36 pm
Location: São Paulo - Brasil

Postby diegopolverelli » Fri Nov 28, 2008 3:35 pm

yo hago

seek xcoddep+xartcodig+xlote
if !eof()

modifico el reg

else

agrego el registro

endif


de esa menera funciona, pero a veces el seek falla, entra por el else, a pesar de existir la combinacion coddep+artcodig+lote, y me da de alta algo que ya existe.

si en lugar del seek uso locate (abro la base sin indexar incluso), no falla nunca. Rarisimo...
diegopolverelli
 
Posts: 149
Joined: Thu Jun 21, 2007 3:26 pm

Postby Armando Picon » Fri Nov 28, 2008 3:49 pm

LOCATE trabaja bien porque ubica la cadena que buscas sin importar el tamaño del campo... Cuando utilizas el índice, el mecanismo de búsqueda es ubicar el valor de tu cadena "con el mismo largo".

Mi sugerencia es que hagas una sentencia como esta, para crear tu índice:

INDEX ON PADL(Libros->Epoca,LEN(Libros->Epoca))+ ;
PADL(Libros->Orden,LEN(Libros->Orden))+ ;
PADL(Libros->numlibro,LEN(Libros->numlibro)) ;
TAG "LIBRO1" TO "LIBROS.CDX"

Como puedes ver en este índice se puede buscar el valor de tu variable + los espacios necesarios para completar el ancho del campo correspondiente...
FWH + BCC582 + WorkShop 4.5 + Resource Hacker + Mingw
Mis nuevas herramientas
Comunicacion via WhatsApp (+51) 957549 665
Comunicación via Correo: apic1002002 at yahoo dot es; apic1002002@gmail.com
User avatar
Armando Picon
 
Posts: 446
Joined: Mon Dec 26, 2005 9:11 pm
Location: Lima, Peru

Postby diegopolverelli » Fri Nov 28, 2008 4:02 pm

yo no uso .cdx

igualmente tengo indices sin usar esto del Len y demas, y funcionan bien; Antes del Seek pongo set softseek off y creo que funciona bien. ¿no tienen conocimiento de algun error aleatorio que se verifique con los indices?

ademas, el locate, si hago:

loca for st->cod=xcod1 .and. st->lote=xlote1

y tengo en st->lote, por ej, a001 y a0012, puede darse que me actualice mal: si xlote1=a001, quisas el locate me de .t. en a0012

¿o no? en fin. Gracias. Atte.
diegopolverelli
 
Posts: 149
Joined: Thu Jun 21, 2007 3:26 pm

Postby Ruben D. Fernandez » Fri Nov 28, 2008 4:10 pm

Diego:
Prueba a poner antes del segundo dBseek(lo_que_buscas) un dbgotop().

Saludos

Ruben Fernandez.
Ruben D. Fernandez
 
Posts: 189
Joined: Sun Jul 08, 2007 1:46 am
Location: Uruguay

Postby karinha » Fri Nov 28, 2008 4:13 pm

xlote1=a001, quisas el locate me de .t. en a0012


mira se no hay una cadena en blanco e retira los blancos con ALLTRIM().

OTRA:

locate for st->cod==xcod1 .and. st->lote==xlote1 //-> Intente asi.

Saludos.
João Santos - São Paulo - Brasil - Phone: +55(11)95150-7341
User avatar
karinha
 
Posts: 7416
Joined: Tue Dec 20, 2005 7:36 pm
Location: São Paulo - Brasil

Postby Armando Picon » Fri Nov 28, 2008 4:17 pm

No necesitas usar el CDX, lo puse solo como ejemplo. Locate te va ha ubicar a001 correctamente si fue introducido primero antes que a0012... en caso contrario SIEMPRE se va ha colocar sobre a0012 porque ya contiene la cadena "a001". En Clipper ese fenómeno no ocurría. Por eso es que empece a utilizar PADL(alias->campo1, LEN(alias->campo1)) con la ventaja adicional que, sin importar las variaciones de la longitud del campo, puedo reindexar... y hasta el presente me funciona al 100%

diegopolverelli wrote:yo no uso .cdx

igualmente tengo indices sin usar esto del Len y demas, y funcionan bien; Antes del Seek pongo set softseek off y creo que funciona bien. ¿no tienen conocimiento de algun error aleatorio que se verifique con los indices?

ademas, el locate, si hago:

loca for st->cod=xcod1 .and. st->lote=xlote1

y tengo en st->lote, por ej, a001 y a0012, puede darse que me actualice mal: si xlote1=a001, quisas el locate me de .t. en a0012

¿o no? en fin. Gracias. Atte.
FWH + BCC582 + WorkShop 4.5 + Resource Hacker + Mingw
Mis nuevas herramientas
Comunicacion via WhatsApp (+51) 957549 665
Comunicación via Correo: apic1002002 at yahoo dot es; apic1002002@gmail.com
User avatar
Armando Picon
 
Posts: 446
Joined: Mon Dec 26, 2005 9:11 pm
Location: Lima, Peru

Postby Carlos Mora » Fri Nov 28, 2008 5:24 pm

Armando,

hacer un PADL(alias->campo1, LEN(alias->campo1)) no tiene sentido en el índice. Hay que hacerlo en la clave, al hacer el seek:

Seek PADL( cVar1, LEN(alias->campo1))+PADL( cVar2, LEN(alias->campo2))+PADL( cVar3, LEN(alias->campo3))

Ahí si tiene sentido. SIEMPRE campo1 tiene una longitud Len(campo1), es una identidad, no cambia nada.

Un saludo,

Carlos.
Saludos
Carlos Mora
http://harbouradvisor.blogspot.com/
StackOverflow http://stackoverflow.com/users/549761/carlos-mora
“If you think education is expensive, try ignorance"
Carlos Mora
 
Posts: 988
Joined: Thu Nov 24, 2005 3:01 pm
Location: Madrid, España

Postby Armando Picon » Fri Nov 28, 2008 8:32 pm

Carlos

Si tiene y muchísimo... mi preferencia es construir el indice con el PAD ya que en adelante no tengo que preocuparme de estar revisando en que parte del codigo, que podrían ser muchísima líneas, debo estar revisando para que no se vaya algo que luego no me devuelva el dato que busco con el Seek o Dbseek... (claro que utilizo rutinas que crean los índices al inicio y mantengo abierto las bases). Por otra parte mis variables de búsqueda las construyo, por ejemplo, vCampo1 := SPACE(LEN(Campo1)) y así sucesivamente de forma tal, que aunque por razones insospechadas tenga que modificar la losngitud del campo, no tengo que realizar ajuste alguno a mi código.

No hace mucho, enfrenté un problema con código parecido a lo que indicas en tu respuesta (realizar un adecuación de codigo contable para pasar de 6 dígitos de cuenta a 8 dígitos) y la verdad que fue horroroso el trabajo... tuve que trabajar a pérdida por que la revisión y modificación de código de terceros es peor que tortura china...!!!


Carlos Mora wrote:Armando,

hacer un PADL(alias->campo1, LEN(alias->campo1)) no tiene sentido en el índice. Hay que hacerlo en la clave, al hacer el seek:

Seek PADL( cVar1, LEN(alias->campo1))+PADL( cVar2, LEN(alias->campo2))+PADL( cVar3, LEN(alias->campo3))

Ahí si tiene sentido. SIEMPRE campo1 tiene una longitud Len(campo1), es una identidad, no cambia nada.

Un saludo,

Carlos.
FWH + BCC582 + WorkShop 4.5 + Resource Hacker + Mingw
Mis nuevas herramientas
Comunicacion via WhatsApp (+51) 957549 665
Comunicación via Correo: apic1002002 at yahoo dot es; apic1002002@gmail.com
User avatar
Armando Picon
 
Posts: 446
Joined: Mon Dec 26, 2005 9:11 pm
Location: Lima, Peru

Postby FranciscoA » Sun Nov 30, 2008 3:14 am

diegopolverelli wrote:yo hago

seek xcoddep+xartcodig+xlote
if !eof()

modifico el reg

else

agrego el registro

endif


de esa menera funciona, pero a veces el seek falla, entra por el else, a pesar de existir la combinacion coddep+artcodig+lote, y me da de alta algo que ya existe.

si en lugar del seek uso locate (abro la base sin indexar incluso), no falla nunca. Rarisimo...



Prueba de esta manera:

seek xcoddep+xartcodig+xlote
if Found() // en vez de !eof()
modifico el reg
else
agrego el registro
endif


O, asi:

if dbseek( xcoddep+xartcodig+xlote )
modifico el reg
else
agrego el registro
endif
User avatar
FranciscoA
 
Posts: 2123
Joined: Fri Jul 18, 2008 1:24 am
Location: Chinandega, Nicaragua, C.A.

Postby Carlos Mora » Mon Dec 01, 2008 2:47 pm

Hola Armando,

Armando Picon wrote:Si tiene y muchísimo...

realmente no me imagino donde podria tener algo que ver, por más que le doy vueltas, no se me ocurre como puede llegar a fallar.

¿Podrías enviarme una dbf con un ejemplo donde:

Code: Select all  Expand view
PADL(alias->campo1, LEN(alias->campo1)) <> alias->campo1


?
En lo que me dices del codigo contable cambiado de 6 a 8, si has cambiado un campo y no has reindexado evidentemente te saldrá mal. Y de hecho Harbour, a diferencia del Clipper, no acepta claves de longitud variable, por lo que usar el indice con las claves a 6 probablemente te hubiese resultado en un 'Corruption detected'. Por ejmplo usar claves variables como alltrim(nombre) falla en harbour en cuanto una clave no tien el mismo largo que la del registro 1.

Respecto de lo valores en blanco, siempre uso el registro fantasma del Eof() como base para los registros en blanco, es algo muy seguro. De hecho hace poco Manu Expósito puso una clase buffer, que es muy parecida a la que uso, y no he tenido nunca problemas.

Un saludo,

Carlos.
Saludos
Carlos Mora
http://harbouradvisor.blogspot.com/
StackOverflow http://stackoverflow.com/users/549761/carlos-mora
“If you think education is expensive, try ignorance"
Carlos Mora
 
Posts: 988
Joined: Thu Nov 24, 2005 3:01 pm
Location: Madrid, España


Return to FiveWin para Harbour/xHarbour

Who is online

Users browsing this forum: FranciscoA and 81 guests