Reputation: 32933
I have a bunch of Access databases, each of which has several tables. Each table has a composite primary key, with varying fields comprising that key.
How can I, for a given table, get the name of the primary key and the names of the fields which are used in it? I.e., what's the SQL to do that? (I need to use raw SQL rather than Visual Basic)
BTW I know that I can open the tables in the Access GUI and see the primary keys there but I need to automate the process so that I can modify the primary keys.
thanks! max
Upvotes: 1
Views: 3936
Reputation: 1193
Well, I am late, but there is a solution without the need of using of ADOX, just with the regular ADODB object model.
This is the function to get the name of the primary index. If there isn't one you will get back the empty string:
Public Function GetPrimaryIndex(ByVal Table As String) As String
Dim RS As ADODB.Recordset
Set RS = CurrentProject.Connection.OpenSchema(adSchemaIndexes, Array(Empty, Empty, Empty, Empty, Table))
With RS
Do Until .EOF
If !PRIMARY_KEY Then GetPrimaryIndex = !INDEX_NAME: Exit Do
.MoveNext
Loop
.Close
End With
Set RS = Nothing
End Function
And here is the function to get the names of the used columns in an index with additional collation (Collation 1 would be ASC, but we normally don't need it), like you would use it in a CREATE INDEX
statement:
Public Function GetIndexFields(ByVal Table As String, ByVal IndexName As String) As String
Dim RS As ADODB.Recordset
Dim Columns As String
Set RS = CurrentProject.Connection.OpenSchema(adSchemaIndexes, Array(Empty, Empty, Empty, Empty, Table))
With RS
Do Until .EOF
If !INDEX_NAME = IndexName Then
Columns = Columns & !COLUMN_NAME
If !COLLATION = 2 Then Columns = Columns & " DESC"
Columns = Columns & ", "
End If
.MoveNext
Loop
.Close
End With
Set RS = Nothing
GetIndexFields = IIf(Len(Columns), Left(Columns, Len(Columns) - 2), "")
End Function
I know, the OP asked for a raw-SQL-only-solution. But - to be honest - I don't know where to find indexes in the hidden system ("MySys") tables nor if that is even possible.
But as reminder: Maybe the OP didn't know that you can use any VBA function in an Access query, not only VBA built in functions, but also your own in local modules programmed functions and even in other Access DBs programmed functions, if you link to that Access DB as a library. So feel free to use this functions in your query.
Upvotes: 2
Reputation: 6780
Here is an Access VBA function that uses ADOX to get the primary Key columns.
Private Function getPrimaryKeyFields(ByRef strFieldNames() As String) As Integer
On Error GoTo HandleErr
Dim intReturn As Integer
'just get the primary key field here.
Dim idx As ADOX.Index
Dim Table As ADOX.Table
Dim col As ADOX.Column
Dim cat As New ADOX.Catalog
Set cat.ActiveConnection = CurrentProject.Connection
Set Table = cat.Tables(mTableName)
Set idx = Table.Indexes("PrimaryKey")
ReDim strFieldNames(idx.Columns.Count)
Dim intCount As Integer
intCount = 0
For Each col In idx.Columns
strFieldNames(intCount) = col.Name
intCount = intCount + 1
Next
intReturn = intCount
Set idx = Nothing
Set Table = Nothing
Set col = Nothing
Set cat = Nothing
ExitHere:
getPrimaryKeyFields = intReturn
Exit Function
HandleErr:
Select Case Err.Number
Case Else
'put some error handling here.
Resume ExitHere
End Select
' End Error handling block.
End Function
Pass in a string array and it is filled in with the field names. Number of fields is returned by the function. Hope this helps.
Seth
Upvotes: 1
Reputation: 300559
Have a look at the ADOX Object Model. Specifically the Key Object:
With the properties and collections of a Key object, you can:
Identify the key with the Name property.
Determine whether the key is primary, foreign, or unique with the Type property.
Access the database columns of the key with the Columns collection.
Specify the name of the related table with the RelatedTable property.
Determine the action performed on deletion or update of a primary key with the DeleteRule and UpdateRule properties.
Also, How to list the primary key columns in an Access table
Update: I think the question originally said programmatically: If you want to use TSQL then you need to query the Hidden System Tables
Upvotes: 0