Получить список индексов в базе данных Access - PullRequest
5 голосов
/ 29 марта 2010

Я знаю, что есть способ получить список всех таблиц в базе данных Access, используя запрос MsysObjects:

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

Кто-нибудь знает подобный (или другой) способ получения списка всех индексов в базе данных MS-Access?

Ответы [ 3 ]

4 голосов
/ 06 ноября 2014

Если вам нужно использовать провайдера .Net OleDb и ничего больше, вы можете использовать

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

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

В индексах DataTable у вас есть индексы и поля вместе.

4 голосов
/ 29 марта 2010

Вы можете проверить 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

Редактировать : Пересмотрен сабвуфер, чтобы игнорировать таблицы MSys * (Access system).

Вы также можете использовать метод 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"))
1 голос
/ 11 августа 2016

Увеличение до Ответ HansUp .

В дополнение к знанию имен индексов почти всегда важно знать, на какие поля ссылаются эти индексы.Например, при импорте таблиц из БД доступа в 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
...