Zur Hauptseite ... Zum Onlinearchiv ... Zum Abonnement ... Zum Newsletter ... Zu den Tools ... Zum Impressum ... Zum Login ...

Gedrucktes Heft

Diesen Beitrag finden Sie in Ausgabe 6/2015.

Unser Angebot für Sie!

Lesen Sie diesen Beitrag und 500 andere sofort im Onlinearchiv, und erhalten Sie alle zwei Monate brandheißes Access-Know-how auf 72 gedruckten Seiten! Plus attraktive Präsente, zum Beispiel das bald erscheinende Buch 'Access 2010 - Das Grundlagenbuch für Entwickler'!

Diesen Beitrag twittern

Probleme mit Primärschlüsseln und Autowert

Primärschlüsselfelder mit Autowert-Funktion bieten eine komfortable Möglichkeit, für neue Datensätze automatisch einen neuen, eindeutigen Primärschlüsselwert zu vergeben. Wenn man zwischendurch keine Datensätze löscht, ist diese Nummerierung sogar lückenlos. Allerdings kann es sein, dass jemand versucht, gelöschte Datensätze mit den fehlenden Primärschlüsselwerten zu ersetzen. Zu welchen Problemen dies führt und wie Sie diese lösen, zeigt der vorliegende Beitrag.

Autowert-Primärschlüsselfelder

Fast alle Tabellen verwenden ein Primärschlüsselfeld, das über die Autowert-Funktion mit einem neuen, noch nicht vergebenen Wert gefüllt wird (s. Bild 1).

Entwurf einer Tabelle mit Autowert-Primärschlüsselfeld

Bild 1: Entwurf einer Tabelle mit Autowert-Primärschlüsselfeld

Mit dem Felddatentyp Autowert legt man automatisch die Eigenschaft Neue Werte auf Inkrement fest, was bedeutet, dass als Primärschlüsselwert beim Neuanlegen von Datensätzen standardmäßig der Primärschlüsselwert des zuletzt angelegten Datensatzes herangezogen und um eins erhöht wird.

Damit ist eine kleine Stolperfalle verbunden, denn dies funktioniert nur, wenn Sie den neuen Datensatz über die Tabelle oder ein an die Tabelle gebundenes Formular eingeben oder dies per VBA erledigen, wobei hier der Primärschlüsselwert explizit nicht festgelegt werden darf, sondern vom System erzeugt werden muss.

Dies erreichen Sie beispielsweise durch folgende kleine Prozedur, die Sie in einem Standardmodul anlegen und per F5 ausführen:

Public Sub NeuerArtikelMitAutowert()
     Dim db As DAO.Database
     Set db = CurrentDb
     db.Execute "INSERT INTO tblArtikel(Artikelname)  VALUES('Beispielartikel')", dbFailOnError
End Sub

Der Autowert wird hier automatisch auf den zuletzt vergebenen Wert plus eins festgelegt.

Die folgende Variante (siehe Prozedur NeuerArtikel_MitVorgegebenemPK im Modul mdlBeispiele) verwendet die folgende INSERT INTO-Anweisung:

db.Execute "INSERT INTO tblArtikel(ArtikelID, Artikelname) VALUES(79, 'Beispielartikel')", dbFailOnError

Diese legt ebenfalls einen neuen Datensatz an, weist dem Primärschlüsselfeld aber den Wert 79 zu. Sofern dieser bereits vergeben ist, löst dies den Fehler 3022 aus.

Wenn Sie einen Datensatz per DAO anlegen, sieht dies so aus:

Public Sub NeuerArtikel_DAO_MitAutowert()
     Dim db As DAO.Database
     Dim rst As DAO.Recordset
     Set db = CurrentDb
     Set rst = db.OpenRecordset("tblArtikel", dbOpenDynaset)
     rst.AddNew
     rst!Artikelname = "Beispielartikel"
     Debug.Print rst!ArtikelID
     rst.Update
End Sub

Auch hier wird der Wert des Feldes ArtikelID nicht explizit zugewiesen, sondern in Abhängigkeit vom Autowert des zuletzt angelegten Datensatzes vergeben. Diesen gibt die Prozedur vor dem Speichern des Datensatzes im Direktfenster aus.

Sie können allerdings auch hier den Primärschlüsselwert per Code vorgeben (siehe NeuerArtikel_DAO_MitVorgegebenemPK):

rst.AddNew
rst!ArtikelID = 83
rst!Artikelname = "Beispielartikel"
rst.Update

Auch hier lösen Sie einen Fehler aus, wenn der angegebene Primärschlüsselwert bereits vergeben ist. Gefährlich ist die Vergabe von Werten für Autowertfelder per Code, weil der hier vergebene Wert als Grundlage für den folgenden, automatisch vergebenen Autowert herangezogen wird.

Wenn Sie also etwa einen anderen Datensatz als den mit dem höchsten Primärschlüsselwert löschen und diesen neu anlegen, wird der Wert des zuletzt vergebenen Primärschlüsselwertes auf genau diesen neu angelegten Wert festgelegt.

Beispiel: Wir haben drei Datensätze mit den Primärschlüsselwerten 81, 82 und 83 und löschen den Datensatz mit dem Wert 82. Dann legen Sie mit folgender Anweisung einen neuen Datensatz mit dem Primärschlüsselwert 82 an:

db.Execute "INSERT INTO tblArtikel(ArtikelID, Artikelname) VALUES(82, 'Beispielartikel')", dbFailOnError

Soweit ist das kein Problem. Wenn Sie aber jetzt in der Datenblattansicht einen weiteren neuen Datensatz anlegen, vergibt Access einen bereits vorhandenen Autowert, nämlich die Nummer 83 (s. Bild 2).

Doppelt vergebener Autowert

Bild 2: Doppelt vergebener Autowert

Dieses Verhalten ist für Otto Normalverbraucher unerwartet, aber nach oben angegebener Erklärung logisch: Der zuletzt angelegte Datensatz hat den Wert 82 im Primärschlüsselfeld erhalten, also muss der aktuelle diesen Wert plus eins erhalten, also 83. Nach dem Bestätigen der Fehlermeldung erscheint dann beim Neuanlegen der folgende Primärschlüsselwert, also die 84.

Wenn Sie in einer großen Tabelle mittendrin einen neuen Datensatz angelegt haben, müssen Sie eine Menge Fehlermeldungen wegklicken, bis Sie wieder einen Datensatz mit noch nicht vergebenem Autowert eingeben können. Einfacher geht es da mit einer Komprimierung der Datenbank – hier wird anscheinend der höchste Wert des Autowertfeldes wieder als zuletzt angelegter Autowert für diese Tabelle festgelegt.

Zusammenfassung

Primärschlüsselfelder mit Autowert sollten nicht zum Durchnummerieren von Datensätzen, sondern lediglich als eindeutiges Kennzeichen von Datensätzen verwendet werden. Ein Einfügen von Datensätzen mit Nummern, die kleiner als die höchste vergebene Nummer sind, kann zu Fehlern führen.

Kompletten Artikel lesen?

Einfach für den Newsletter anmelden, dann lesen Sie schon in einer Minute den kompletten Artikel und erhalten die Beispieldatenbanken.

E-Mail:

Download

Download

Die .zip-Datei enthält folgende Dateien:

Primaerschluesselprobleme.mdb

Beispieldateien downloaden

© 2003-2015 André Minhorst Alle Rechte vorbehalten.