none
Abfragen ob Spalte PrimaryKey ist

    Frage

  • Moin

    ich habe da ein Stück Code der mir zurück gibt ob ein Feld ein Indizes hat

    doch leider funktioniert das nicht bei dem PrimaryKey Feldern - kann ich diesen in dieser/ähnlicher form auch abfragen?

    Public Function DAO_IndexExists(pdbs As DAO.Database, _
                                    ByVal psTable As String, _
                                    ByVal psIDxName As String) As Boolean
        Dim S As String
        On Error Resume Next
        S = pdbs.TableDefs(psTable).Indexes(psIDxName).Name
        DAO_IndexExists = (Err.Number = 0)
     
    End Function

    Montag, 21. Oktober 2013 16:02

Antworten

  • Hallo Michael,

    Zwei Schnipsel aus einem uralten Upsizing Projekt:

        Dim tdf As DAO.TableDef ' wird vorher ermittelt 
        Dim idx As DAO.Index
        Dim fldIndex As DAO.Field
        ' Primärschlüssel ermitteln (Felder müssen NOT NULL sein)
        For Each idx In tdf.Indexes
            If idx.Primary = True Then
                Exit For
            End If
        Next idx

    brauchst Du nur den Test, so kannst Du True zurückliefern, wenn Primary gefunden wird.

    Falls es für Dein anderes Projekt ist, wie ich vermute - der Code, um daraus einen SQL Server PRIMARY KEY zu erzeugen:

        ' Primärschlüssel erzeugen
        strContext = "CREATE PRIMARY"
        If Not idx Is Nothing Then
            ' Verwendeten Index Namen eintragen
            CurrentDb.Execute "UPDATE ztTableIndex SET SQLIndexName='pk" & tdf.Name & "' " & _
                                      "WHERE TableID=" & TableID & " AND IndexName='" & idx.Name & "';"
    
            strSQL = strSQL & vbCrLf & Space(4) & "CONSTRAINT pk" & tdf.Name & " PRIMARY KEY "
            strFields = ""
            For Each fldIndex In idx.Fields
                ' Wenn mit Identität kein CLUSTERED (ist default)
                Set fld = tdf.Fields(fldIndex.Name)
                If ((fld.Attributes And dbAutoIncrField) = dbAutoIncrField) Then
                    strSQL = strSQL & " NONCLUSTERED "
                End If
                If strFields <> "" Then strFields = strFields & ", "
                strFields = strFields & fldIndex.Name
            Next fldIndex
            strSQL = strSQL & "(" & strFields & ")"
        Else
            strSQL = Left(strSQL, Len(strSQL) - 1)             ' Letztes Komma entfernen
        End If
        strSQL = strSQL & vbCrLf & ")"

    Im zweiten Teil fehlt einiges, es sollte aber erkennbar sein was passiert. Dabei wird u. a. ein eindeutiger Name für den Primärschlüssel festgelegt (und für später gespeichert). Access tut das von Haus nicht, beim SQL Server aber notwendig ist (gleiches gilt für eindeutige Einschränkungen usw.).
    Warnung: Da bei dem Projekt nur "saubere" Tabellen/Spalten-Namen vorkamen, wurden die Bezeichner direkt verwendet, falls das bei Dir anders ist wäre der Code für Namen mit Leerzeichen etc noch zu erweitern.

    Gruß Elmar

    • Als Antwort markiert MCDPone Dienstag, 22. Oktober 2013 05:54
    Montag, 21. Oktober 2013 18:12

Alle Antworten

  • Hallo Michael,

    Zwei Schnipsel aus einem uralten Upsizing Projekt:

        Dim tdf As DAO.TableDef ' wird vorher ermittelt 
        Dim idx As DAO.Index
        Dim fldIndex As DAO.Field
        ' Primärschlüssel ermitteln (Felder müssen NOT NULL sein)
        For Each idx In tdf.Indexes
            If idx.Primary = True Then
                Exit For
            End If
        Next idx

    brauchst Du nur den Test, so kannst Du True zurückliefern, wenn Primary gefunden wird.

    Falls es für Dein anderes Projekt ist, wie ich vermute - der Code, um daraus einen SQL Server PRIMARY KEY zu erzeugen:

        ' Primärschlüssel erzeugen
        strContext = "CREATE PRIMARY"
        If Not idx Is Nothing Then
            ' Verwendeten Index Namen eintragen
            CurrentDb.Execute "UPDATE ztTableIndex SET SQLIndexName='pk" & tdf.Name & "' " & _
                                      "WHERE TableID=" & TableID & " AND IndexName='" & idx.Name & "';"
    
            strSQL = strSQL & vbCrLf & Space(4) & "CONSTRAINT pk" & tdf.Name & " PRIMARY KEY "
            strFields = ""
            For Each fldIndex In idx.Fields
                ' Wenn mit Identität kein CLUSTERED (ist default)
                Set fld = tdf.Fields(fldIndex.Name)
                If ((fld.Attributes And dbAutoIncrField) = dbAutoIncrField) Then
                    strSQL = strSQL & " NONCLUSTERED "
                End If
                If strFields <> "" Then strFields = strFields & ", "
                strFields = strFields & fldIndex.Name
            Next fldIndex
            strSQL = strSQL & "(" & strFields & ")"
        Else
            strSQL = Left(strSQL, Len(strSQL) - 1)             ' Letztes Komma entfernen
        End If
        strSQL = strSQL & vbCrLf & ")"

    Im zweiten Teil fehlt einiges, es sollte aber erkennbar sein was passiert. Dabei wird u. a. ein eindeutiger Name für den Primärschlüssel festgelegt (und für später gespeichert). Access tut das von Haus nicht, beim SQL Server aber notwendig ist (gleiches gilt für eindeutige Einschränkungen usw.).
    Warnung: Da bei dem Projekt nur "saubere" Tabellen/Spalten-Namen vorkamen, wurden die Bezeichner direkt verwendet, falls das bei Dir anders ist wäre der Code für Namen mit Leerzeichen etc noch zu erweitern.

    Gruß Elmar

    • Als Antwort markiert MCDPone Dienstag, 22. Oktober 2013 05:54
    Montag, 21. Oktober 2013 18:12
  • DANKE für deine Hilfe
    Dienstag, 22. Oktober 2013 05:55