代码之家  ›  专栏  ›  技术社区  ›  waanders

检索Access数据库中的索引列表

  •  5
  • waanders  · 技术社区  · 14 年前

    我知道有一种方法可以通过查询msysobjects来获取Access数据库中所有表的列表:

    SELECT MSysObjects.Name FROM MsysObjects
    WHERE
      Left$([Name],1)<>'~' AND
      Left$([Name],4)<>'Msys' AND
      MSysObjects.Type=1
    

    有人知道检索MS Access数据库中所有索引列表的类似(或其他)方法吗?

    3 回复  |  直到 8 年前
        1
  •  4
  •   HansUp    11 年前

    你可以检查 TableDef 对象以访问索引名称。

    Public Sub ShowIndexNames()
        Dim tdf As TableDef
        Dim idx As Index
        Dim num_indexes As Long
    
    On Error GoTo ErrorHandler
    
        For Each tdf In CurrentDb.TableDefs
            num_indexes = tdf.Indexes.Count
            If Left$(tdf.Name, 4) <> "MSys" Then
                If num_indexes > 0 Then
                    For Each idx In tdf.Indexes
                        Debug.Print tdf.Name, idx.Name
                    Next idx
                End If
             End If
        Next tdf
    
    ExitHere:
        Exit Sub
    
    ErrorHandler:
        Select Case Err.Number
        Case 3110
            'Could not read definitions; no read definitions '
            'permission for table or query '<Name>'. '
            Debug.Print "No read definitions permission for " _
                & tdf.Name
            num_indexes = 0
            Resume Next
        Case Else
            Debug.Print Err.Number & "-> " & Err.Description
            GoTo ExitHere
        End Select
    End Sub
    

    编辑 :将SUB修改为忽略MSYS*(访问系统)表。

    你也可以使用ADO OpenSchema 方法来检索有关索引的信息。下面的代码列出了索引名、关联表以及索引是否为主键。我写它是为了使用ADO的后期绑定,因为这不需要为 Microsoft ActiveX数据对象[版本]库 .

    Const adSchemaIndexes As Long = 12
    Dim cn As Object ' ADODB.Connection
    Dim rs As Object ' ADODB.Recordset
    Dim i As Long
    
    Set cn = CurrentProject.Connection
    Set rs = cn.OpenSchema(adSchemaIndexes)
    With rs
        ' enable next three lines to view all the recordset column names
    '    For i = 0 To (.Fields.Count - 1)
    '        Debug.Print .Fields(i).Name
    '    Next i
        Do While Not .EOF
           Debug.Print !TABLE_NAME, !INDEX_NAME, !PRIMARY_KEY
           .MoveNext
        Loop
        .Close
    End With
    Set rs = Nothing
    Set cn = Nothing
    

    如果您更喜欢检查单个表的索引,而不是数据库中的每个表的索引,请将表名作为数组的第五个元素传递。

    Set rs = cn.OpenSchema(adSchemaIndexes, Array(Empty, Empty, Empty, Empty, "tblFoo"))
    
        2
  •  4
  •   bubi    10 年前

    如果您需要使用.NET OLEDB提供程序,并且不能再使用其他任何内容

    DataTable indexes = 
    (myOleDbConnection.GetOleDbSchemaTable(
    System.Data.OleDb.OleDbSchemaGuid.Indexes,
    new object[] { null, null, null, null, tableName});
    

    (指定正确的连接和正确的表)。

    在索引数据表中,索引和字段都在一起。

        3
  •  1
  •   Community datashaman    7 年前

    扩大到 HansUp's answer .

    除了知道索引的名称外,几乎总是必须知道这些索引中引用了哪些字段。例如,当将表从访问数据库导入到SQL Server 2008 R2时,它不会复制键和索引,因此我需要重新生成它们。因此,这个脚本不能正确地处理外键约束,但应该生成主键和标准索引。排序FK问题时,我将对其进行编辑。

    Public Sub Generate_tSQLIndex()
        Dim tdf As TableDef
        Dim idx As Index
        Dim num_indexes As Long
        Dim indexdef_tsql As String
        Dim pk As Boolean
        On Error GoTo ErrorHandler
        For Each tdf In CurrentDb.TableDefs
            num_indexes = tdf.Indexes.Count
            If Left$(tdf.Name, 4) <> "MSys" Then
                If num_indexes > 0 Then
                    For Each idx In tdf.Indexes
                        pk = idx.Primary
                        If pk Then indexdef_tsql = "ALTER TABLE [" + tdf.Name + "] WITH CHECK ADD CONSTRAINT [PK_" + tdf.Name + "_" + idx.Name + "] PRIMARY KEY " Else indexdef_tsql = "CREATE "
                        If idx.Unique And Not pk Then indexdef_tsql = indexdef_tsql + "UNIQUE "
                        If idx.Clustered Then indexdef_tsql = indexdef_tsql + "CLUSTERED " Else indexdef_tsql = indexdef_tsql + "NONCLUSTERED "
                        If Not pk Then indexdef_tsql = indexdef_tsql + "INDEX [" + idx.Name + "] ON [" + tdf.Name + "] "
                        indexdef_tsql = indexdef_tsql + "("
                        For Each fld In idx.Fields
                            indexdef_tsql = indexdef_tsql + "[" + fld.Name + "]"
                            If fld.Attributes = 1 Then indexdef_tsql = indexdef_tsql + " DESC, " Else indexdef_tsql = indexdef_tsql + " ASC, "
                        Next fld
                        If idx.Fields.Count > 0 Then indexdef_tsql = Left(indexdef_tsql, Len(indexdef_tsql) - 2)
                        indexdef_tsql = indexdef_tsql + ")"
                        Debug.Print indexdef_tsql
                    Next idx
                End If
             End If
        Next tdf
    
    ExitHere:
            Exit Sub
    
    ErrorHandler:
        Select Case Err.Number
            Case 3110
            'Could not read definitions; no read definitions '
            'permission for table or query '<Name>'. '
            Debug.Print "No read definitions permission for " + tdf.Name
            num_indexes = 0
            Resume Next
        Case Else
            Debug.Print Err.Number & "-> " & Err.Description
            GoTo ExitHere
        End Select
    
    End Sub