35.4 Neue Autoinkrementwerte abrufen
Fügen Sie der Tabelle Products eine neue Datenzeile hinzu, wird ein Primärschlüsselwert generiert, der automatisch von der Datenbank erzeugt wird. Nicht alle Datenbanken unterstützen dieses Feature, aber der SQL Server gehört dazu. Das Problem bei der Aktualisierung durch Hinzufügen einer neuen Datenzeile ist, dass der DataRow im DataSet nach der Aktualisierung der von der Datenbank erzeugte Primärschlüssel nicht zur Verfügung steht, während jede andere Aktualisierung dazu führt, dass die DataRowVersion.Original den Wert von DataRowVersion.Current annimmt.
Wie also erhalten wir nach dem Hinzufügen den neuen, aktuellen Primärschlüssel einer Autoinkrementspalte? Hier hilft uns der SQL Server mit seiner integrierten Funktion @@IDENTITY. Sie liefert den letzten erzeugten Autoinkrementwert zurück.
Wir können das Beispiel aus dem letzten Abschnitt nun in der Weise ergänzen, dass wir für unsere beiden hinzuzufügenden Datenzeilen die entsprechenden Werte im Ereignishandler zu RowUpdated abfragen und der Spalte ProduktID der betreffenden Datenzeile zuordnen.
static void da_RowUpdated(object sender, SqlRowUpdatedEventArgs e) {
// Konfliktanalyse
if (e.Status == UpdateStatus.ErrorsOccurred) {
[...]
}
// Abfrage der neuen Autoinkrementwerte
else if ((e.Status == UpdateStatus.Continue) &&
(e.StatementType == StatementType.Insert)) {
SqlCommand cmdPS = new SqlCommand();
cmdPS.CommandText = "SELECT @ProductID = @@IDENTITY";
cmdPS.Connection = con;
SqlParameter param = cmdPS.Parameters.Add("@ProductID", SqlDbType.Int);
param.Direction = ParameterDirection.Output;
cmdPS.ExecuteNonQuery();
e.Row["ProductID"] = cmdPS.Parameters["@ProductID"].Value;
}
}
Listing 35.9 Abfrage der neuen Primärschlüsselwerte
Zunächst muss sichergestellt werden, dass nur die erfolgreiche Aktualisierung einer neu hinzugefügten Datenzeile vom folgenden Code behandelt wird. Die Eigenschaften Status und StatementType des EventsArgs-Objekts gestatten uns eine entsprechende Filterung.
Im Anweisungsblock wird zuerst ein SqlCommand-Objekt erzeugt. Der CommandText-Eigenschaft weisen wir mit
SELECT @ProductID = @@IDENTITY
den Rückgabewert von @@IDENTITY zu. Der Parameter @ProductID muss als Ausgabeparameter festgelegt werden. Nach dem Aufruf der Methode ExecuteNonQuery können wir dem Parameter den neuen Wert entnehmen und ihn in die Spalte ProductID der entsprechenden Datenzeile schreiben. Bevor Sie die Anwendung testen, müssen Sie noch berücksichtigen, dass aufgrund des Aufrufs von FillSchema die Spalte ProductID schreibgeschützt ist. Sie müssen deshalb mit
ds.Tables[0].Columns["ProductID"].ReadOnly = false;
vor dem Aufruf der Update-Methode des SqlDataAdapters den Schreibschutz wieder aufheben.
Das komplette Beispiel finden Sie auf der Buch-DVD unter ...\Beispiele\Kapitel 35\AutoInkrementSample.
Ihre Meinung
Wie hat Ihnen das Openbook gefallen? Wir freuen uns immer über Ihre Rückmeldung. Schreiben Sie uns gerne Ihr Feedback als E-Mail an kommunikation@rheinwerk-verlag.de.