![]() |
Datenbank: MS-SQL • Version: Express2014 • Zugriff über: ADO
id des soeben angelegten Datensatzes?
Hallo,
ich arbeite mich gerade in die Wissenschaft der Datenbanken ein. Ich habe hier Microsoft SQL Server Express Edition (64-bit, Version 12.0.6108 SP3) zur Verfügung, Datenbank erstellte/beobachte ich mit dem Microsoft SQL Server Management Studio. :!: Ich versuche seit Tagen die id des soeben erfolgreich mit Insert angelegtem Datensatz auszulesen. Die OH ist leider unverständlich für mich, aus verschiedenen Foren habe ich allerlei erfolglos versucht (ich sollte "allerlei" vielleicht beschreiben, da es aber zu nichts führte... :roll: ). Ich las, daß nach dem Insert der Zeiger auf dem Datensatz stünde - ja das ist fein, aber ich weiß trotzdem nicht, wie ich dann daraus die automatisch erstellte id ermittle (ADOQuery.recNo sagt 1 aber das ist nicht der Wert von id)!? Wenn das Projekt fertig ist, werden ca. 10 Clients mitunter gleichzeitig Datensätze anlegen - folglich sollte ich nicht einfach die zuletzt generiert id auslesen, sondern diejenige, die ich gerade selbst generiert habe. Ich habe gelesen, daß die Datensätze clientbezogen angelegt werden und deshalb nichts durcheinander kommen kann - aber trotzdem kann ich ja nicht einfach fragen, welches ist die letzte id, denn die könnte ja 1 µs nach meiner id angelegt worden sein und bekomme dann die falsche id-Nummer... (bin mir da nicht sicher) Mit einem nachfolgenden
Delphi-Quellcode:
und ExecSQL bzw. Open weiß ich aber nicht, wie/wo ich das Ergebnis lesen kann...
db.ADOQuery.SQL.Text:='SELECT max(id) FROM tabelle';
Für Euch sind das bestimmt Basics :oops: ich lerne das aber erst :| Vereinfacht dargestellt mache ich so das Insert (das auch funktioniert):
Delphi-Quellcode:
Danach versuchte ich es zunächst mit
db.ADOQuery.paramCheck:=true;
db.ADOQuery.SQL.Text:='INSERT into Tabelle (foo1,foo2,foo3) '+ 'Values (:foo1,:foo2,:foo3) '; db.ADOQuery.Parameters.ParamByName('foo1').Value:=s; db.ADOQuery.Parameters.ParamByName('foo2').Value:=strtoint(copy(s,3,2)); db.ADOQuery.Parameters.ParamByName('foo3').Value:=strtoint(copy(s,1,2)); db.ADOQuery.ExecSQL;
Delphi-Quellcode:
Die Fehlermeldung sagt aber nur "Das Feld 'id' wurde nicht gefunden" - ist aber sehr wohl in der Tabelle vorhanden als primary key.
idstring:=db.ADOQuery['id'];
Sowas wie
Delphi-Quellcode:
in die SQL-Anfrage zu notieren, bringt mir einen anderen Fehler ein und geht auch nicht.
RETURN id
:?: Ich vermute aber, ich muss nach dem ExecSQL noch was dazuschreiben...?
Delphi-Quellcode:
hilft mir auch nicht, weiß nicht wie ich das Ergebnis lese...
SELECT max(id) FROM tabelle
Oder wird in der ADOQuery-Komponente etwas automatisch aktualisiert, woraus ich die id ganz einfach auslesen kann? Ich brauche die id, um diesen Datensatz in weiteren Datensätzen anderer Tabellen zu verknüpfen. Ich habe auch noch ADOCommand, ADOTable, ADODataset, ADOConnection und Datasource zur Verfügung, die ich aber ohne Komponenten erst zu Laufzeit initialisiere und "verdrahte". Gibt es vielleicht nach dem ExecSQL auch dort irgendwo eine Wertaktualisierung?? Was kann ich tun oder wie geht es bitte? |
AW: id des soeben angelegten Datensatzes?
Da SQL ein riesiges Thema ist, antworte ich in Form einer bereits diskutierten Variante:
![]() Da steht Dein Thema aus vielen Gesichtspunkten beantwortet :-) Grüße |
AW: id des soeben angelegten Datensatzes?
Hallo,
Zitat:
Query.Open; Id:= Query.Fields[0].AsInteger Aber ob das wirklich dein Eintrag ist, oder der des Nachbarn, der kurz nach dir etwas eingetragen hat ... Ich gehe immer über Sequenzen, lasse mir also vor dem Insert eine neue Nummer geben. BeiMS-SQL kannst du das Feld auch mit dem Feldtyp Identity angeben. Den Wert bekommst Du hiermit: ![]() |
AW: id des soeben angelegten Datensatzes?
Ich glaube der Standard könnte die RETRUN Anweisung sein, die solche ID zurückliefert.
Bei ms sql gibt es jedenfalls dafür die OUTPUT Clause. Bedeutet, ein Insert liefert seine neue ID selbst zurück (sofern es entsprechend mit OUTPUT Clause formuliert ist) |
AW: id des soeben angelegten Datensatzes?
Ich mach das so...
Delphi-Quellcode:
Query.SQL.Add('INSERT INTO TABELLE ... VALUES ...');
Query.SQL.Add('SELECT SCOPE_IDENTITY() AS [SCOPE_IDENTITY]'); Query.Open; if (Query.RecordCount = 1) then begin RecID:=Query.Fields.FieldByName('SCOPE_IDENTITY').AsString; ... end; |
AW: id des soeben angelegten Datensatzes?
Die Lösung von EmWieMichael ist mMn die korrekte, so mache ich das auch.
Der Fehler vom TE kommt daher, dass es in der Query
Code:
keinen Spaltennamen id gibt, er aber versucht, darauf zuzugreifen. Ist aber wie gesagt auch der falsche Ansatz, denn genau dafür gibt es IDENTITY. Beachte, dass man Identitätsfelder nicht selbst schreiben kann. Kennt man von MySQL anders.
SELECT max(id) FROM tabelle
|
AW: id des soeben angelegten Datensatzes?
Zitat:
Doch, geht auch mit MSSQL; die DB wäre für mich sonst auch unbrauchbar:
Delphi-Quellcode:
Query.SQL.Add('SET IDENTITY_INSERT TABELLE ON');
Query.SQL.Add('INSERT INTO TABELLE ... VALUES ...'); Query.SQL.Add('SET IDENTITY_INSERT TABELLE OFF'); Query.ExecSQL; Result:=(Query.RowsAffected = 1); |
erledigt: id des soeben angelegten Datensatzes?
:thumb: Dankeschön an alle, die Empfehlung von EmWieMichael trifft es genau.
:kiss: |
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:09 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz