
Cuando se dañan los archivos índices de una tabla, ejecutar el comando REINDEX a veces no es suficiente. Hay casos en que hay que generar nuevamente cada uno de los índices con el comando INDEX ON y/o ALTER TABLE.
El siguiente código lo utilizo como una herramienta para regenerar rápidamente todos los índices de todas las tablas de una base de datos, y aparte me genera un archivo PRG con nombre "REG_CDX_????????.PRG" (donde "????????" es el nombre de la base de datos) que lo puedo ejecutar posteriormente
Si la base de datos contiene relaciones persistentes e integridad referencial NO ejecuten el código publicado, ni el archivo .PRG generado ya que éstos eliminan todas las etiquetas de índices de la tabla (DELETE TAG ALL) y esta acción también elimina el archivo .CDX y quita las relaciones persistentes entre las tablas y la integridad referencial existentes en la base de datos. Si éste es su caso, puede utilizar la herramienta GenDBC.PRG que está en la carpeta \Tools\Gendbc\ en la carpeta raíz de instalación de Visual FoxPro, que si respalda y restaura las relaciones y la IR.
Usen este código bajo sus propios riesgos. Hagan una copia de seguridad de la base de datos antes de probarlo.
* -----
* Configurando la variable llRegenera en:
* .T. = si desea que se regeneren todos los índices al momento de ejecutar el código
* .F. = solo genera un archivo PRG con el código para generarlos posteriormente
*-----
LOCAL laDBF[1], laTag[1], llRegenera, lnI, lnJ, lnTAG
LOCAL lcCmd, lcDBC, lcPRG, lcTabla, lnDBF, loExc
CLOSE TABLES ALL
CLOSE DATABASES ALL
CLEAR ALL
SET MEMOWIDTH TO 128
SET SAFETY OFF
#DEFINE CR_LF CHR(13)+CHR(10)
*-- Selecciono DBC
m.lcDBC = GETFILE([DBC])
*-- Solo genera PRG o genera PRG y regenera índices
m.llRegenera = .F.
*-- Nombre del PRG generado
m.lcPRG = [REG_CDX_] + FORCEEXT(JUSTFNAME(m.lcDBC), [PRG])
IF EMPTY(m.lcDBC) OR NOT FILE(m.lcDBC)
MESSAGEBOX([Debe seleccionar un archivo DBC], 16)
RETURN
ENDIF
CLEAR
STRTOFILE([*--- Regenera los índices compuestos de las tablas de la base de datos ] + ;
JUSTFNAME(m.lcDBC) + CR_LF, m.lcPRG, 0)
STRTOFILE([*--- ] + CHRTRAN(TTOC(DATETIME(), 3), [T], [ ]) + CR_LF + CR_LF, m.lcPRG, 1)
OPEN DATABASE (m.lcDBC) && EXCLUSIVE VALIDATE
SET DATABASE TO (JUSTSTEM(m.lcDBC))
STRTOFILE([OPEN DATABASE ("] + m.lcDBC + [") EXCLUSIVE VALIDATE] + CR_LF, m.lcPRG, 1)
STRTOFILE([SET DATABASE TO ] + JUSTSTEM(m.lcDBC) + CR_LF + CR_LF, m.lcPRG, 1)
m.lnDBF = ADBOBJECTS(laDBF, "TABLE")
ASORT(m.laDBF)
FOR m.lnI = 1 TO m.lnDBF
*-- Recorro todas las tablas de la DBC
m.lcTabla = ADDBS(JUSTPATH(DBC())) + m.laDBF(m.lnI)
TRY
IF m.llRegenera && Necesito abrir en modo EXCLUSIVE
USE (m.lcTabla) EXCLUSIVE IN SELECT(m.laDBF(m.lnI))
ELSE
USE (m.lcTabla) SHARED IN SELECT(m.laDBF(m.lnI))
ENDIF
STRTOFILE([USE ("] + m.lcTabla + [") EXCLUSIVE ] + CR_LF, m.lcPRG, 1)
m.lnTAG = ATAGINFO(laTag)
m.lcCmd = ""
FOR m.lnJ = 1 TO m.lnTAG
*-- Recorro todas las etiquetas de índices
IF m.laTag(m.lnJ, 2) = [PRIMARY]
m.lcCmd = m.lcCmd + ;
[ALTER TABLE ] + m.laDBF(m.lnI) + [ ADD PRIMARY KEY ] + m.laTag(m.lnJ, 3) + ;
[ TAG ] + m.laTag(m.lnJ, 1) + ;
[ COLLATE "] + m.laTag(m.lnJ, 6) + ["] + CR_LF
ELSE
m.lcCmd = m.lcCmd + ;
[INDEX ON ] + m.laTag(m.lnJ, 3) + [ ] + ;
[TAG ] + m.laTag(m.lnJ, 1) + [ ] + ;
IIF(m.laTag(m.lnJ, 2) = "BINARY", m.laTag(m.lnJ, 2) + [ ], m.laTag(m.lnJ, 5) + [ ]) + ;
IIF(EMPTY(m.laTag(m.lnJ, 4)), [], [FOR ] + m.laTag(m.lnJ, 4) + [ ]) + ;
IIF(m.laTag(m.lnJ, 2) = "CANDIDATE", m.laTag(m.lnJ, 2) + [ ], []) + ;
[COLLATE "] + m.laTag(m.lnJ, 6) + ["] + CR_LF
ENDIF
ENDFOR
IF m.llRegenera
DELETE TAG ALL
PACK
EXECSCRIPT(m.lcCmd)
ENDIF
STRTOFILE([DELETE TAG ALL] + CR_LF, m.lcPRG, 1)
STRTOFILE([PACK] + CR_LF + CR_LF, m.lcPRG, 1)
STRTOFILE(m.lcCmd + CR_LF, m.lcPRG, 1)
CATCH TO m.loExc
STRTOFILE([* ERROR:] + CR_LF, m.lcPRG, 1)
STRTOFILE([* ] + m.loExc.MESSAGE + CR_LF, m.lcPRG, 1)
FINALLY
USE IN SELECT(m.laDBF(m.lnI))
STRTOFILE([USE IN SELECT("] + m.laDBF(m.lnI) + [")] + CR_LF + CR_LF, m.lcPRG, 1)
ENDTRY
ENDFOR
MODIFY FILE (m.lcPRG)
No hay comentarios. :
Publicar un comentario
Los comentarios son moderados, por lo que pueden demorar varias horas para su publicación.