Plateforme Level Extreme
Abonnement
Profil corporatif
Produits & Services
Support
Légal
English
VFP=always problems with indexes. Legend or not ?
Message
De
08/09/2000 15:08:14
Keith Jones
The It Studio Limited
Brentwood, Royaume Uni
 
Information générale
Forum:
Visual FoxPro
Catégorie:
Autre
Divers
Thread ID:
00414111
Message ID:
00414358
Vues:
48
Nope is the answer to your question,
unles the server goes down or user
turns off PC for example.

Two progs here will recreate indices automatically.
Run CreateDataDict first, read message boxes.

It is no use running CreateIndices after indices
are broken if you have not first run CreateDataDict.

Hope this is of some help,

Keith




** CreateDataDict.PRG
* Written by Keith Jones (but should I admit to it).
* This programme creates a data dictionary of tables into a Table called
* DataDict. DataDict also contains the names of tables which do not
* have indices so it can also be used in a Pack and Reindex routine.

cSetDefault=FullPath("")
SetExclusive=SET("Exclusive")
cSafety=SET("SAFETY")
CLOSE TABLES
CLOSE DATA ALL
CLOSE ALL
SET SAFETY OFF
SET EXCLUSIVE OFF
ACTIVATE WINDOW VIEW

cDataDirectory=GETDIR()
IF EMPTY(cDataDirectory)
RETURN
ENDIF

SET DEFAULT TO &cDataDirectory

IF FILE("DataDict.DBF")
DELETE FILE DataDict.DBF
ENDIF

IF USED("DataD")
USE IN DataD
ENDIF

CREATE CURSOR DataD (TableName C(50), TagName C(20), IndexNum N(3), POrC C(1), IndexExp C(100))

* Get all DBFs in directory
DIMENSION DBFNames(1,5)
nNumDBFs=ADIR("DBFNames", "*.DBF")
=ASORT("DBFNames")

FOR nCount = 1 TO nNumDBFs
IF DBFNames(nCount,1) # "DATAD.DBF" AND DBFNames(nCount,1) # "FIELDNAME.DBF"
USE DBFNames(nCount,1) IN 0
SELECT DBFNames(nCount,1)
cTableName=ALIAS()
* Find out how many tags.
nNumTags=1
DO WHILE NOT EMPTY(SYS(14, nNumTags))
nNumTags = nNumTags + 1
ENDDO
nNumTags=nNumTags - 1
IF nNumTags > 1 && Has TAGS, insert all information into DactDict.
FOR nCount1 = 1 TO nNumTags
cTagName=TAG(nCount1)
cIndexExp=SYS(14, nCount1)
* Store number of index.
nIndexNum=nCount1
* Is index Primary or Candidate?
cPOrC=""
IF PRIMARY(nCount1)
cPOrC="P"
ENDIF
IF CANDIDATE(nCount1)
cPOrC="C"
ENDIF
INSERT INTO DataD (TableName, TagName, IndexNum, POrC, IndexExp) VALUES ;
(cTableName, cTagName, nIndexNum, cPOrC, cIndexExp)
ENDFOR
ELSE && No tags, insert table name into DataDict.
INSERT INTO DataD (TableName) VALUE (cTableName)
ENDIF
USE IN (cTableName)
ENDIF
ENDFOR

SELECT * FROM DataD INTO CURSOR KJ ORDER BY TableName, TagName

USE IN DataD && Get rid of cursor.

IF FILE("DataDict.DBF")
DELETE FILE DataDict.DBF
ENDIF

CREATE TABLE DataDict (TableName C(50), TagName C(20), IndexNum N(3), ;
POrC C(1), IndexExp C(100))

SELECT DataDict
=CURSORSETPROP("Buffering",1,"DataDict") && SET BUFFERING OFF.
ZAP
SET EXCLUSIVE OFF

APPEND FROM DBF("KJ") FOR NOT EMPTY(TagName)

CLOSE TABLES

* Now get all field names for all tables.
IF FILE("FieldName.DBF")
DELETE FILE FieldName.DBF
ENDIF
SELECT 0
CREATE TABLE FieldName (TableName C(50), FieldName C(50), FieldNum N(4), FieldWidth N(10), FieldType C(1))

FOR nCount = 1 TO nNumDBFs
IF DBFNames(nCount, 1) # "DATADICT.DBF" AND ;
DBFNames(nCount, 1) # "FIELDNAME.DBF"
USE DBFNames(nCount, 1) IN 0
SELECT DBFNames(nCount, 1)
cTableName=ALIAS()
* Find out how many fields.
nNumFields=AFIELDS(cArrayName)
* Get field names and insert into FieldNa dbf.
FOR nCount1 = 1 TO nNumFields
cFieldName=FIELD(nCount1)
nFieldNum=nCount1
nFieldWidth=FSIZE(FIELD(nCount1))
cFieldType=VARTYPE(EVALUATE(cTableName + "." + cFieldName))
INSERT INTO FieldName (TableName, FieldName, FieldNum, FieldWidth, FieldType) VALUES ;
(cTableName, cFieldName, nFieldNum, nFieldWidth, cFieldType)
ENDFOR
USE IN (cTableName)
ENDIF
ENDFOR

SELECT * FROM FieldName INTO CURSOR KJ ORDER BY TableName, FieldName

USE IN FieldName
SET EXCLUSIVE ON
USE FieldName IN 0

SELECT FieldName
=CURSORSETPROP("Buffering",1,"FieldName") && Set buffering off.
ZAP
SET EXCLUSIVE OFF
APPEND FROM DBF("KJ")

CLOSE DATABASE ALL
CLOSE TABLES
USE DataDict IN 0
USE FieldName IN 0 && Not associated with a database.

SET EXCLUSIVE &SetExclusive
SET SAFETY &cSafety
SET DEFAULT TO &cSetDefault
RELEASE ALL
CANCEL
* End of programme CreateDataDict.

************************************************************
************************************************************


** Programm CreateIndex.

* Written by Keith Jones, but should I admit to it?

cSetEscape=SET("Escape")
SET ESCAPE OFF
cSetExclusive=SET("Exclusive")
cSetSafety=SET("safety")
cSetDefault=FULLPATH("")

MESSAGEBOX("This programme will-:" + CHR(13) + CHR(13) + ;
"1) Delete all indices." + CHR(13) + ;
"2) Pack all tables." + CHR(13) + ;
"3) Recreate from scratch all indices.", 48, ;
"Programme Actions")

* Make sure not run by mistake.
* If you have not created or populated table DataDict with the latest
* table information, you will loose all your indices forever.
IF MESSAGEBOX("Before you run this programme, you MUST run the programme" + CHR(13) + ;
"CreateDataDict OR get your backup copy of the file DataDict.DBF." + CHR(13) + CHR(13) + ;
"If you do not have an up to date copy of the table DataDict.DBF," + CHR(13) + ;
"you will loose your indices information forever." + CHR(13) + CHR(13) + ;
"This means FOREVER."+ CHR(13) + CHR(13) + ;
"Select NO to cancel this operation.", 4, ;
SPACE(35) + "!!!!!!!!!!!! WARNING !!!!!!!!!!!!")=7
SET ESCAPE &cSetEscape
RETURN
ENDIF

cDataDirectory=GETDIR()
IF EMPTY(cDataDirectory)
RETURN
ENDIF

IF NOT FILE(cDataDirectory + "DataDict.DBF")
MESSAGEBOX("Table DataDict.DBF not found." + CHR(13) + CHR(13) + ;
"You must have a current version" + CHR(13) + ;
"of this file!!!!!!", 48, "Please Run Programme CreateDataDict")
RETURN
ENDIF

SET DEFAULT TO &cDataDirectory

CLOSE ALL
SET EXCLUSIVE ON
SET SAFETY OFF
SELECT DISTINCT TableName FROM DataDict INTO CURSOR DeleteIndex

SCAN
WAIT WINDOW TIMEOUT 0.1
USE (ALLTRIM(DeleteIndex.TableName)) IN 0
SELECT (ALLTRIM(DeleteIndex.TableName))
WAIT WINDOW "Deleting TAGS in Table " + ALLTRIM(DeleteIndex.TableName) NOWAIT
DELETE TAG ALL
WAIT WINDOW "Packing Table " + ALLTRIM(DeleteIndex.TableName) NOWAIT
PACK
ENDSCAN

IF NOT USED("DataDict")
USE DataDict IN 0
ENDIF

SELECT DataDict
SCAN
WAIT WINDOW TIMEOUT 0.1
cTableName=ALLTRIM(DataDict.TableName)
SELECT (cTableName)
cTagName=ALLTRIM(DataDict.TagName)
cIndexEpr=ALLTRIM(DataDict.IndexExp)
DO CASE
CASE DataDict.POrC="P"
WAIT WINDOW "Creating PRIMARY KEY " + cTagName + " In Table " + ;
cTableName NOWAIT
ALTER TABLE &cTableName ADD PRIMARY KEY &cIndexEpr TAG &cTagName
CASE DataDict.POrC="C"
WAIT WINDOW "Creating CANDIDATE INDEX " + cTagName + " In Table " + ;
cTableName NOWAIT
INDEX ON &cIndexEpr TAG &cTagName CANDIDATE
OTHERWISE
WAIT WINDOW "Creating REGULAR INDEX " + cTagName + " In Table " + ;
cTableName NOWAIT
INDEX ON &cIndexEpr TAG &cTagName
ENDCASE
SET ORDER TO
ENDSCAN

SET ESCAPE &cSetEscape
SET EXCLUSIVE &cSetExclusive
SET SAFETY &cSetSafety
SET DEFAULT TO &cSetDefault

WAIT WINDOW "PACK and RECREATE INDICIES completed."

* End of programme.
Précédent
Répondre
Fil
Voir

Click here to load this message in the networking platform