Problemas indice
-
- Posts: 149
- Joined: Thu Jun 21, 2007 3:26 pm
Problemas indice
Hola. Tengo una aplicacion que usa un indice que se compone de 3 _ 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.
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.
-
- Posts: 149
- Joined: Thu Jun 21, 2007 3:26 pm
ejemplo
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...!!!
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...!!!
-
- Posts: 149
- Joined: Thu Jun 21, 2007 3:26 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...
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...
- Armando Picon
- Posts: 448
- Joined: Mon Dec 26, 2005 9:11 pm
- Location: Lima, Peru
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...
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
Mis nuevas herramientas
Comunicacion via WhatsApp (+51) 957549 665
Comunicación via Correo: apic1002002 at yahoo dot es; apic1002002@gmail.com
-
- Posts: 149
- Joined: Thu Jun 21, 2007 3:26 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.
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.
-
- Posts: 189
- Joined: Sun Jul 08, 2007 1:46 am
- Location: Uruguay
- Armando Picon
- Posts: 448
- Joined: Mon Dec 26, 2005 9:11 pm
- Location: Lima, Peru
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
Mis nuevas herramientas
Comunicacion via WhatsApp (+51) 957549 665
Comunicación via Correo: apic1002002 at yahoo dot es; apic1002002@gmail.com
-
- Posts: 988
- Joined: Thu Nov 24, 2005 3:01 pm
- Location: Madrid, España
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.
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
http://harbouradvisor.blogspot.com/
StackOverflow http://stackoverflow.com/users/549761/carlos-mora
“If you think education is expensive, try ignorance"
- Armando Picon
- Posts: 448
- Joined: Mon Dec 26, 2005 9:11 pm
- Location: Lima, Peru
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...!!!
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
Mis nuevas herramientas
Comunicacion via WhatsApp (+51) 957549 665
Comunicación via Correo: apic1002002 at yahoo dot es; apic1002002@gmail.com
- FranciscoA
- Posts: 1964
- Joined: Fri Jul 18, 2008 1:24 am
- Location: Chinandega, Nicaragua, C.A.
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
-
- Posts: 988
- Joined: Thu Nov 24, 2005 3:01 pm
- Location: Madrid, España
Hola Armando,
¿Podrías enviarme una dbf con un ejemplo donde:
?
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.
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.Armando Picon wrote: Si tiene y muchísimo...
¿Podrías enviarme una dbf con un ejemplo donde:
Code: Select all
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
http://harbouradvisor.blogspot.com/
StackOverflow http://stackoverflow.com/users/549761/carlos-mora
“If you think education is expensive, try ignorance"