Glengamoi (Forum) · AspHeute · .NET Heute (RSS-Suche) · AspxFiles (Wiki) · .NET Blogs

Zugriff auf autom. generierte ID beim Einfügen eines Datensatzes

Geschrieben von: Christian Koller
Kategorie: Datenbank

This printed page brought to you by AlphaSierraPapa

Bei der Implementation einer Datenbank auf einem relationalen Datenbanksystem, wie Microsoft SQL Server 7.0 oder Microsoft Access 2000, verwendet man zur Referenzierung von Datensätzen in Tabellen eine sogenannte ID.

Das Wort ID ist die Kurzform für Identifier, oder zu deutsch, Identifikationsnummer. ID's haben für gewöhnlich ganzzahlige Werte. (Für Datenbankprofis: Ich verwende in diesem Artikel ID synonym für Primärschlüssel).

Der Wert im ID-Feld eines Datensatzes dient zur eindeutigen Identifikation des Datensatzes. Aus diesem Grunde muß der ID-Wert eindeutig sein, und darf kein zweites mal in der ID-Spalte der Tabelle vorkommen.

SQL Server 7.0 und Access 2000 verfügen über bestimmte Feldtypen, die automatisch beim Einfügen eines neuen Datensatzes in eine Tabelle eine neue und eindeutige ID für den eingefügten Datensatz erzeugen, und diese mit den Daten abspeichert. Unter SQL Server 7.0 sind solche Felder als Identity Felder bekannt, in Access 2000 kennt man sie als Autonumbers oder Autovalues.

Die Aufgabe des ID-Feldes ist es, einen Datensatz eindeutig zu identifizieren. Für das Auffinden, Ändern und Löschen eines Datensatzes kann man bei Angabe der ID sichergehen, daß nur der beabsichtigte Datensatz tatsächlich manipuliert wird. Datenbankintern legt man über ID-Spalten oft einen Index, um so die Suchgeschwindigkeit bei allen Datenbankaktionen und Befehlen, die bestimmte ID-Werte ansprechen, zu optimieren. Auch bei der Verknüpfung von Datensätzen (meist unterschiedlicher Tabellen), zum Beispiel mit dem SQL-Operator JOIN, referenziert man die ID-Werte der zu verknüpfenden Datensätze.

Wenn man nun unter ADO einen neuen Datensatz in eine Tabelle einfügt, ist es oftmals sehr nützlich zu wissen, welchen Wert die generierte ID des gerade abgespeicherten Datensatzes hat. Dies ist insbesondere dann wichtig, wenn man nach dem Abspeichern des Hauptdatensatzes in einer Tabelle noch weitere Datensätze in verknüpften Tabellen abspeichern will. Der Grund dafür ist, daß die ID des Hauptdatensatzes beim Abspeichern der verknüpften Datensätze mitangegeben werden muß.

Datenbankbeispiel zur Illustration:

In einer Personendatenbank werden Projekte und Projektaufgaben gespeichert. Jedes Projekt wird durch einen Datensatz in der Tabelle tProjekt repräsentiert. Jedem neuen Projekt wird beim Speichern in der Tabelle tProjekt automatisch eine ProjektID zugewiesen.

Weiters werden alle Aufgaben, die für das Projekt zu erledigen sind, in der Tabelle tAufgaben gespeichert. Natürlich hat auch diese Tabelle ein ID-Feld mit dem Namen AufgabenID zur eindeutigen Identifikation jeder Aufgabe.

Um zu kennzeichnen, welche Aufgaben zu einem bestimmten Projekt gehören, verwendet man ein Verknüpfungsfeld in der Tabelle tAufgaben. Dieses Feld in der Tabelle tAufgaben enthält den Wert der ProjektID des Projektes, zu dem die Aufgabe gehört. Das Verknüpfungsfeld, nennen wir es einmal FK_ProjektID, stellt einen sogenannten Fremdschlüssel in Beziehung zum Primärschlüssel (=ID-Feld namens ProjektID) der Tabelle tProjekt dar.

Die Verknüpfung der Tabellen tProjekt und tAufgaben erfolgt also über die Spalte ProjektID der Tabelle tProjekt und die Spalte FK_ProjektID der Tabelle tAufgabe.

Das folgende Beispiel legt nun ein neues Projekt an, indem es den zugehörigen Datensatz in der Tabelle tProjekt speichert:

<% @Language = VBScript %>
<%
' Beispielwerte:
Dim strProjektName, strProjektLeiter
strProjektName   = "Zeus"
strProjektLeiter = "Christoph Wille"

' Rueckgabewert aus Tabelle: ProjektID
Dim lngProjektID

' Variablen fuer Datenbankverbindung
Dim conn, rs
Dim strConnection

' Datenbankverbindung (Connectionstring) definieren:
strConnection = "DSN=Projekte; Database=Projekte;"
strConnection = strConnection & "UID=sa;PWD="
Set conn = CreateObject("ADODB.Connection")

' Datenbankverbindung (Connection) oeffnen:
conn.Open strConnection

' Recordset fuer Zugriff auf Tabellendaten oeffnen:
Set rs = CreateObject("ADODB.Recordset")
rs.CursorLocation = 2   ' adUseServer
rs.CursorType     = 1   ' adOpenKeyset 
rs.LockType       = 3   ' adLockOptimistic

' Verbindung zu Tabelle tProjekt aufbauen:
strSQL = "SELECT * FROM tProjekt WHERE ProjektID = 0"
' Syntax: rs.Open (Tabellennamen oder SQL-Befehl), ConnectionObject
rs.Open strSQL, conn

' Datensatz in Tabelle tProjekt einfuegen:
rs.AddNew 
rs("ProjektName")   = strProjektName
rs("ProjektLeiter") = strProjektLeiter
rs.Update

' Auslesen der ProjektID:
lngProjektID = rs("ProjektID")

' Schliessen des Recordsets und der Connection
rs.Close
conn.Close

' Ausgeben der ID zum User:
Response.Write "Die Projekt-ID des Projektes "
Response.Write strProjektName & " ist: "
Response.Write lngProjektID & "<br>" & vbCrLf

' Resourcen des Recordset- und Connection Objektes
'   freigeben:
Set rs   = Nothing
Set conn = Nothing
%>

Das Skript beinhaltet die folgende Funktionalität, die das Auslesen einer automatisch generierten ID ermöglicht:

Eine Datenbankverbindung wird mittels conn.Open etabliert:

' Datenbankverbindung (Connectionstring) definieren:
strConnection = "DSN=Projekte; Database=Projekte;"
strConnection = strConnection & "UID=sa;PWD="
Set conn = CreateObject("ADODB.Connection")
' Datenbankverbindung (Connection) oeffnen:
conn.Open strConnection

Zum Connection Objekt und zu ODBC DNS siehe auch die Artikel Eigenschaften der Connection und Recordset Objekte und ODBC und ASP - Eine DSN zur Verwendung mit ASP definieren.

Dann wird das Recordset rs erstellt und vorbereitet:

' Recordset fuer Zugriff auf Tabellendaten oeffen:
Set rs = CreateObject("ADODB.Recordset")
rs.CursorLocation = 2   ' adUseServer
rs.CursorType     = 1   ' adOpenKeyset 
rs.LockType       = 3   ' adLockOptimistic

Das Setzen der CursorLocation auf adUseServer bewirkt, daß der Recordset Cursor von der Datenbank, und nicht von ADO oder dem Datenbankprovider (wie ODBC oder OLE DB), verwaltet wird. Dies ist notwendig, um direkten Zugriff auf den von der Datenbank automatisch generierten ID-Wert zu erhalten.

Der CursorType wird auf adOpenKeyset gesetzt. Danach werden alle Änderungen in der Datenquelle des Recordsets, also Änderungen in der Tabelle der Datenbank, unmittelbar an das Recordset weitergegeben. Dies bewirkt, daß der ID-Wert sofort nach dem Einfügen eines neuen Datensatzes mit rs.AddNew und rs.Update im Recordset zur Verfügung steht und nach dem Befehl rs.Update aus dem entsprechenden Recordset-Feld ausgelesen werden kann.

Der Recordset LockType von adLockOptimistic ist notwendig, um überhaupt einen neuen Datensatz mittels rs.Update in die Tabelle einfügen zu können. Optional könnte man auch einen LockType von adLockBatchOptimistic (Wert = 4) benutzen, um sogenannte Batch-Updates mittles rs.UpdateBatch durchzuführen, die das Einfügen oder Ändern mehrerer Datensätze auf einmal erlauben.

Um einen neuen Datensatz zur Tabelle hinzuzufügen, wird ein ADO Recordset als Schnittstelle zwischen ASP-Skript und Datenbanktabelle benutzt. Um einen neuen Datensatz resourcen-schonend zur Tabelle hinzuzufügen, öffnet man mittles rs.Open Befehl das Recordset, ohne jedoch einen Datensatz aus der Datenbank darin zu speichern:

strSQL = "SELECT * FROM tProjekt WHERE ProjektID = 0"
rs.Open strSQL, conn

Nachdem das Recordset geöffnet ist, fügt man einen neuen Datensatz zum Recordset hinzu:

' Datensatz in Tabelle tProjekt einfuegen:
rs.AddNew 
rs("ProjektName")   = strProjektName
rs("ProjektLeiter") = strProjektLeiter
rs.Update

Vor dem Aufrufen des rs.Update Befehls existiert der Datensatz übrigens nur im Recordset. Erst mit dem Aufruf von rs.Update wird der Datensatz aus dem Recordset in die Tabelle geschrieben. Dabei wird von der Datenbank eine ID (in diesem Fall im Feld ProjektID) generiert. Der Wert der ID ist aufgrund der Einstellungen des Recordsets (CursorType, CursorType, LockType) sofort im Recordset sichtbar. So kann der Wert für die ProjektID aus dem Recordset-Feld rs("ProjektID") ausgelesen werden:

' Auslesen der ProjektID:
lngProjektID = rs("ProjektID")

Danach schließt das Skript das Recordset und Connection Objekt und gibt die Resourcen der Objekte frei.

Schlußbemerkung

Die in diesem Artikel vorgestellte Möglichkeit, eine automatisch generierte ID eines neuen Datensatzes auszulesen, ist wohl die eleganteste und sicherste Möglichkeit, dies zu tun.

Obgleich das Öffnen eines Recordsets mit datenbankserver-seitigen, keyset Cursor und optimistic Locking einiges an Resourcen (am Webserver und am Datenbankserver) benötigt, wird dieser Nachteil durch das einfache Auslesen der generierten ID direkt aus dem Recordset mehr als aufgewogen.

Bei dem Einfügen eines Datensatzes mittles des SQL Befehl INSERT ist das Auslesen einer generierten ID nur sehr umständlich (und damit auch Fehleranfällig) über Umwege möglich.

This printed page brought to you by AlphaSierraPapa

Download des Codes

Klicken Sie hier, um den Download zu starten.
http://www.aspheute.com/code/20000606.zip

Verwandte Artikel

ADO und ASP - Datenbanken einmal näher betrachtet
http:/www.aspheute.com/artikel/19990825.htm
Eigenschaften der Connection und Recordset Objekte
http:/www.aspheute.com/artikel/19990811.htm
ODBC und ASP - Eine DSN zur Verwendung mit ASP definieren
http:/www.aspheute.com/artikel/19990826.htm
Records zählen mit Stored Procedures
http:/www.aspheute.com/artikel/20010326.htm
Session State bei parallelen Browser-Frames und Fenstern
http:/www.aspheute.com/artikel/20000830.htm

 

©2000-2006 AspHeute.com
Alle Rechte vorbehalten. Der Inhalt dieser Seiten ist urheberrechtlich geschützt.
Eine Übernahme von Texten (auch nur auszugsweise) oder Graphiken bedarf unserer schriftlichen Zustimmung.