2010-03-29 71 views
4

我知道有一種方法,通過使用quering的MsysObjects得到Access數據庫中所有表的列表:檢索索引列表中的Access數據庫

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

有誰知道類似的(或其它)如何檢索MS-Access數據庫中的所有索引列表?

回答

4

您可以檢查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的(接入系統)表。

您也可以使用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 

如果您希望檢查單個表的索引而不是db中的每個表的索引,請將表名作爲數組的第五個元素傳遞。

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

HansUp>謝謝 – waanders 2010-03-30 06:55:29

1

如果您需要使用的.Net OLEDB提供,僅此而已,你可以使用

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

(specifing正確的連接和右表)。

在索引DataTable中,您有索引和字段。

1

增強至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