2010-03-29 6 views
4

Je sais qu'il ya un moyen d'obtenir une liste de toutes les tables dans une base de données Access en utilisant les Quering les MSysObjects:Récupérer liste des index dans une base de données Access

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

Quelqu'un sait-il un semblable (ou autre) façon de récupérer une liste de tous les index dans une base de données MS-Access?

Répondre

4

Vous pouvez examiner les objets TableDef pour accéder aux noms d'index.

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 

Modifier: Révision de la sous ignorer les tables MSys * (système d'accès).

Vous pouvez également utiliser la méthode OpenSchema d'ADO pour récupérer des informations sur les index. Le code ci-dessous répertorie le nom d'index, la table associée et si l'index est la clé primaire. Je l'ai écrit pour utiliser la liaison tardive pour ADO car cela ne nécessite pas de définir la référence pour Microsoft ActiveX Data Objects [version] Bibliothèque.

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 

Si vous préférez examiner les index pour une seule table plutôt que pour chaque table dans la db, passer le nom de table comme le cinquième élément d'un tableau.

Set rs = cn.OpenSchema(adSchemaIndexes, Array(Empty, Empty, Empty, Empty, "tblFoo")) 
+0

HansUp> Merci – waanders

1

Si vous devez utiliser .Net fournisseur de OleDb et rien de plus, vous pouvez utiliser

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

(specifing la bonne connexion et la table à droite).

Dans les index DataTable vous avez tous les index et les champs tous ensemble.

1

Augmentation à HansUp's answer.

En plus de connaître les noms des index, il est presque toujours essentiel de savoir quels champs sont référencés dans ces index. Par exemple, lors de l'importation de tables à partir d'un DB d'accès vers SQL Server 2008 R2, les clés et les index ne sont pas copiés. Je dois donc les régénérer. Ainsi, ce script ne gère pas correctement les contraintes de clé étrangère, mais devrait générer des clés primaires ainsi que des index standards. Je l'éditerai quand les issues de FK sont triées.

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