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

Posted

技术标签:

【中文标题】检索 Access 数据库中的索引列表【英文标题】:Retrieve list of indexes in an Access database 【发布时间】:2010-03-29 09:43:54 【问题描述】:

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

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

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

【问题讨论】:

【参考方案1】:

您可以检查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 Data Objects [version] Library 设置引用。

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】:

如果您需要使用 .Net OleDb 提供程序而仅此而已

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

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

在索引 DataTable 中,您可以同时拥有索引和字段。

【讨论】:

【参考方案3】:

扩充至HansUp's answer。

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

Public Sub Generate_tSQLIndex()
    Dim tdf As TableDef
    Dim fld As DAO.Field
    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

【讨论】:

谢谢你。很有用。您需要添加一个额外的行 Dim fld As DAO.Field

以上是关于检索 Access 数据库中的索引列表的主要内容,如果未能解决你的问题,请参考以下文章

如何从地图列表中逐列检索飞镖中的数据?

如何遍历列表并检索最小值的索引但忽略输出列表中的重复项?

id索引更改怎么重新抽取索引内容

如何在不刷新网页的情况下从下拉列表索引更改事件的数据库中检索数据

如何使用 itextsharp 从 PDF 的列表框中检索用户选择的索引?

所有从 php 中的 ms access 数据库中检索数据