【问题标题】:VFP. Re-creating indexes虚拟机。重新创建索引
【发布时间】:2017-01-06 14:27:06
【问题描述】:

我希望能够为作为数据库一部分的表重新创建索引。

表的索引已损坏,因此无法打开表(当然不是没有错误消息)。我想使用数据库容器中的信息来重建索引(带有几个标签)

也许我可以为用户提供一种工具来浏览数据库中的表列表,然后选择一个表(或者可能全部)进行重新索引或打包。已查看 DBGETPROP() 和 CURSORGETPROP() 函数调用,但没有找到可以提供所需信息的选项。

一如既往,感谢您的指导。


谢谢添马舰。是的,我一直在打开 .dbc,但后来想要标签名称和索引表达式。

我想做的是建立一个游标,其中包含数据库中每个表的标记名称和索引表达式的详细信息。

据我所知,我需要从 .dbc 中获取表的名称,然后打开每个表以查找其索引。我认为这些只是在表本身而不是在.dbc 中。可以看到 SYS(14) 函数会给我索引表达式,而 TAG() 会给我标签名称;这是要走的路,还是已经有一些功能可以为我做这些事情?

【问题讨论】:

    标签: indexing visual-foxpro recreate


    【解决方案1】:

    您不应该依赖 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
    

    【讨论】:

      【解决方案2】:

      数据库容器是一个表,所以你可以用USE打开它来读取那里的数据。

      【讨论】:

      • 谢谢。我已通过编辑问题做出回应,以寻求进一步澄清。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-08-23
      • 2019-05-10
      • 2014-02-11
      • 2018-04-05
      • 1970-01-01
      • 2018-09-06
      • 2012-10-20
      相关资源
      最近更新 更多