VFP. Повторное создание индексов

Я хотел бы иметь возможность воссоздать индекс для таблицы, которая является частью базы данных.

Индекс таблицы поврежден, поэтому таблица не может быть открыта (конечно, без сообщения об ошибке). Я хотел бы использовать информацию в контейнере базы данных для восстановления индекса (с его несколькими тегами)

Возможно, я мог бы предложить пользователю возможность просмотреть список таблиц в базе данных, а затем выбрать одну таблицу (или, возможно, все) для повторной индексации или упаковки. Я просмотрел вызовы функций DBGETPROP () и CURSORGETPROP (), но не нашел вариантов, которые дают мне необходимую информацию.

Как всегда, благодарен за руководство.


Спасибо, Тамар. Да, я открывал .dbc, но потом мне понадобились имена тегов и выражения индекса.

Я хотел бы создать курсор с подробностями об именах тегов и индексных выражениях для каждой таблицы в базе данных.

Насколько я понимаю, мне нужно получить имена таблиц из .dbc, а затем открыть каждую таблицу, чтобы найти ее индексы. Думаю, это только в самих таблицах, а не в .dbc. Вы можете видеть, что функция SYS (14) выдаст мне индексные выражения, а TAG () выдаст мне имена тегов; Так ли это, или уже есть какая-то функция, которая сделает это за меня?


person Andrew_46    schedule 30.08.2016    source источник


Ответы (2)


Контейнер базы данных - это таблица, поэтому вы можете открыть ее с помощью USE для чтения данных.

person Tamar E. Granor    schedule 30.08.2016
comment
Спасибо. Я ответил, отредактировав вопрос, чтобы получить дополнительные разъяснения. - person Andrew_46; 31.08.2016

Вы не должны полагаться на dbc, чтобы найти и предпринять какие-либо действия после этого. В любом случае у него нет индексной информации (за исключением некоторых, таких как PK, поле индексируется и т. Д., Что не имеет большого значения). Иногда, открывая базу данных исключительно (и имея доступ исключительно к ее таблицам), а затем выполняя:

validate database recover

помогает, но на это тоже нельзя полагаться. Чтобы правильно воссоздать индексы, вы должны удалить их все (или удалить файлы CDX), а затем воссоздать заново.

Если это поможет, ниже приведен код утилиты, который я написал и использую в «ремонте» в случае необходимости. Он создает своего рода словарь данных как для Dbc, так и для бесплатных таблиц:

* CreateDictionary.prg
* Author: Cetin Basoz
* CreateDictionary('c:\mypath\v210\data','','zipcodes,states')
* Creates DataDictionary files in 'DataDic' directory (Default if not specified)
* using 'c:\mypath\v210\data' dir as source data dir
* adds zipcodes and states.dbf as static files (with data as is)
* tcUserStatic - tables that should be kept on user as is
Lparameters tcDataDir, tcDicDir, tcStaticList, tcUserStaticList
tcDataDir = iif(type('tcDataDir')='C' and directory(addbs(m.tcDataDir)), addbs(m.tcDataDir), sys(5)+curdir())
tcDicDir = iif(type('tcDicDir')='C' and !empty(m.tcDicDir), addbs(m.tcDicDir), 'DataDic\')
tcStaticList = iif(Type('tcStaticList')='C',trim(m.tcStaticList),'')
If !directory(justpath(m.tcDicDir))
    Md (justpath(m.tcDicDir))
Endif
Close data all
lnDatabases = adir(arrDBC,m.tcDataDir+'*.dbc')
Create table (m.tcDicDir+'DBCreator') (DBCName M nocptrans, FileBin M nocptrans, Filename c(128) nocptrans)
for ix = 1 to m.lnDatabases
    open data (m.tcDataDir+arrDBC[m.ix,1])
    do home()+'Tools\Gendbc\gendbc' with forceext(m.tcDicDir+arrDBC[m.ix,1],'PRG')
    compile (forceext(m.tcDicDir+arrDBC[m.ix,1],'PRG'))
    insert into (m.tcDicDir+'DBCreator') ;
        values (arrDBC[m.ix,1], ;
        FileToStr(forceext(m.tcDicDir+arrDBC[m.ix,1],'FXP')), ;
        forceext(arrDBC[m.ix,1],'FXP'))
    erase (forceext(m.tcDicDir+arrDBC[m.ix,1],'PRG'))
    erase (forceext(m.tcDicDir+arrDBC[m.ix,1],'FXP'))
    if file(forceext(m.tcDicDir+arrDBC[m.ix,1],'KRT'))
        insert into (m.tcDicDir+'DBCreator') ;
            values (arrDBC[m.ix,1], ;
            FileToStr(forceext(m.tcDicDir+arrDBC[m.ix,1],'KRT')),;
            forceext(arrDBC[m.ix,1],'KRT'))
        erase (forceext(m.tcDicDir+arrDBC[m.ix,1],'KRT'))
    endif   
endfor
Close data all

Create cursor crsSTRUCTS ;
    (FIELD_NAME C(128) nocptrans, ;
    FIELD_TYPE C(1), ;
    FIELD_LEN N(3, 0), ;
    FIELD_DEC N(3, 0), ;
    FIELD_NULL L, ;
    FIELD_NOCP L, ;
    _TABLENAME M nocptrans)
Create cursor crsINDEXES ;
    (TAG_NAME C(10) nocptrans, ;
    KEY_EXPR M, ;
    NDXTYPE C(1), ;
    IS_DESC L, ;
    FILTEREXPR M nocptrans, ;
    _TABLENAME M nocptrans)
Select 0
lnTables = adir(arrTables,m.tcDataDir+'*.dbf')
For ix=1 to m.lnTables
    Use (m.tcDataDir+arrTables[m.ix,1])
    if empty(cursorgetprop('Database'))
        lnFields=afields(arrStruc)
        For jx=1 to m.lnFields
            arrStruc[m.jx,7]=arrTables[m.ix,1]
        Endfor
        Insert into crsSTRUCTS from array arrStruc
        Release arrStruc
        If tagcount()>0
            Dimension arrIndexes[tagcount(),6]
            For jx=1 to tagcount()
                arrIndexes[m.jx,1] = tag(m.jx)
                arrIndexes[m.jx,2] = key(m.jx)
                arrIndexes[m.jx,3] = iif(Primary(m.jx),'P',iif(Candidate(m.jx),'C',iif(unique(m.jx),'U','R')))
                arrIndexes[m.jx,4] = descending(m.jx)
                arrIndexes[m.jx,5] = sys(2021,m.jx)
                arrIndexes[m.jx,6] = arrTables[m.ix,1]
            Endfor
            Insert into crsINDEXES from array arrIndexes
        Endif
    endif
    Use
Endfor
Select crsSTRUCTS
Copy to (m.tcDicDir+'NewStruc')
Select crsINDEXES
Copy to (m.tcDicDir+'NewIndexes')

Create table (m.tcDicDir+'static') (FileName M nocptrans, FileBin M nocptrans)
If !empty(m.tcStaticList)
    lnStatic = alines(arrStatic,chrtran(m.tcStaticList,',',chr(13)))
    For ix = 1 to m.lnStatic
        lnFiles = adir(arrFiles,m.tcDataDir+trim(arrStatic[m.ix])+'.*')
        For jx=1 to m.lnFiles
            If inlist(justext(arrFiles[m.jx,1]),'DBF','CDX','FPT')
                Insert into (m.tcDicDir+'static') values ;
                    (arrFiles[m.jx,1], FileToStr(m.tcDataDir+arrFiles[m.jx,1]))
            Endif
        Endfor
        Release arrFiles
    Endfor
Endif

CREATE TABLE (m.tcDicDir+'userstatic') (FileName c(50))
If !empty(m.tcUserStaticList)
    lnUserStatic = alines(arrUserStatic,chrtran(m.tcUserStaticList,',',chr(13)))
    For ix = 1 to m.lnUserStatic
        lnFiles = adir(arrFiles,m.tcDataDir+trim(arrUserStatic[m.ix])+'.*')
        For jx=1 to m.lnFiles
            If inlist(justext(arrFiles[m.jx,1]),'DBF','CDX','FPT')
                Insert into (m.tcDicDir+'userstatic') values (arrFiles[m.jx,1])
            Endif
        Endfor
        Release arrFiles
    Endfor
Endif
close data all
close tables all
person Cetin Basoz    schedule 01.09.2016