![]() |
Datenbank: SQLite • Version: 3 • Zugriff über: Lazarus, SQLite3Connection
LastRowID wie auslesen?
Hallo,
ich möchte die letzte eingefügte ID auslesen, aber ich scheitere an der Syntax und brauche Hilfe. Hier mein Code:
Delphi-Quellcode:
Nun an welcher Stelle und vor allem wie lese ich diese aus?
procedure TForm2.InsertNewJob();
begin Form1.SQLQuery1.Close; Form1.SQLQuery1.SQL.Text := 'INSERT INTO tbmain VALUES(NULL, :title, :start, :ende, :memo, :fk_category_id, NULL, NULL, :fk_status_id, NULL)'; Form1.SQLQuery1.ParamByName('title').AsString := TitleEdit.Text; Form1.SQLQuery1.ParamByName('start').AsDateTime := StartDateEdit.Date; Form1.SQLQuery1.ParamByName('ende').AsDateTime := EndeDateEdit.Date; Form1.SQLQuery1.ParamByName('memo').AsString := Memo.Text; Form1.SQLQuery1.ParamByName('fk_category_id').AsInteger := Integer(CategoryComboBox.Items.Objects[CategoryComboBox.ItemIndex]); Form1.SQLQuery1.ParamByName('fk_status_id').AsInteger := 1; Form1.SQLQuery1.ExecSQL; Form1.SQLTransaction1.Commit; // Letze id auslesen Form1.SQLQuery1.Close; Form1.SQLQuery1.SQL.Text := 'SELECT last_insert_rowid() FROM tbmain'; Form1.SQLQuery1.Open; showmessage(inttostr(last_insert_rowid())); // funktioniert nicht end; |
AW: LastRowID wie auslesen?
|
AW: LastRowID wie auslesen?
Danke!
|
AW: LastRowID wie auslesen?
Eventuell kennt das SQLQuery1 oder die Connection auch eine LastInsertRowId-Methode.
|
AW: LastRowID wie auslesen?
Zitat:
Habe es jetzt wie folgt (siehe // Die letzte ID auslesen) gelöst. Aber die Lösung mit der LastRowID wird wohl mit anderen DBanken nicht funktionieren nehme ich an. Muss da wohl was anderes ausdenken, damit meine Anwendung auch mit MySQL später arbeiten kann.
Delphi-Quellcode:
procedure TForm2.InsertNewJob();
var CategoryLastID: Integer; begin Form1.SQLQuery1.Close; Form1.SQLQuery1.SQL.Text := 'INSERT INTO tbmain VALUES(NULL, :title, :start, :ende, :memo, :fk_category_id, NULL, NULL, :fk_status_id, NULL)'; Form1.SQLQuery1.ParamByName('title').AsString := TitleEdit.Text; Form1.SQLQuery1.ParamByName('start').AsDateTime := StartDateEdit.Date; Form1.SQLQuery1.ParamByName('ende').AsDateTime := EndeDateEdit.Date; Form1.SQLQuery1.ParamByName('memo').AsString := Memo.Text; // Kategorie nicht vorhanden und ComboBox nicht leer, also erst neue Kategorie in die DB schreiben if (CategoryComboBox.ItemIndex = -1) and (CategoryComboBox.Text <> '') and (CategoryComboBox.Items.IndexOf(CategoryComboBox.Text) = -1) then begin // String manuell reingeschrieben, String sonst in der CB nicht vorhanden // Kategorie in die Tabelle tbcategory schreiben Form1.SQLQueryCategory.Close; Form1.SQLQueryCategory.SQL.Text := 'INSERT INTO tbcategory VALUES(NULL, :category)'; Form1.SQLQueryCategory.ParamByName('category').AsString := CategoryComboBox.Text; Form1.SQLQueryCategory.ExecSQL; Form1.SQLTransaction1.Commit; // Die letzte ID auslesen Form1.SQLQueryCategory.Close; Form1.SQLQueryCategory.SQL.Text := 'SELECT last_insert_rowid() as id_tbcategory FROM tbcategory'; Form1.SQLQueryCategory.Open; CategoryLastID := Form1.SQLQueryCategory.FieldByName('id_tbcategory').AsInteger; Form1.SQLQuery1.ParamByName('fk_category_id').AsInteger := CategoryLastID; end else if (CategoryComboBox.ItemIndex = -1) and (CategoryComboBox.Items.IndexOf(CategoryComboBox.Text) <> -1) then begin // String manuell reingeschrieben, String in der CB vorhanden Form1.SQLQuery1.ParamByName('fk_category_id').AsInteger := Integer(CategoryComboBox.Items.Objects[CategoryComboBox.Items.IndexOf(CategoryComboBox.Text)]); end else if CategoryComboBox.ItemIndex <> -1 then begin // String in der CB ausgewählt Form1.SQLQuery1.ParamByName('fk_category_id').AsInteger := Integer(CategoryComboBox.Items.Objects[CategoryComboBox.ItemIndex]) end; Form1.SQLQuery1.ParamByName('fk_status_id').AsInteger := 1; Form1.SQLQuery1.ExecSQL; Form1.SQLTransaction1.Commit; end; Eine andere Frage... wenn ein Feld leer ist, muss ich in die DB ein NULL schreibe, oder reicht es wenn ich das Attribut gar nicht anfasse? |
AW: LastRowID wie auslesen?
Bei Parametern muss man vorsichtig sein, möglicherweise wird dann der Feld vom letzten Vorgang genommen. Also besser explizit auf NULL setzen.
|
AW: LastRowID wie auslesen?
Zitat:
Delphi-Quellcode:
Form1.SQLQuery1.ParamByName('fk_category_id').AsInteger := nil;
|
AW: LastRowID wie auslesen?
IIRC:
Delphi-Quellcode:
ParamByName('fk_category_id').Clear;
|
AW: LastRowID wie auslesen?
Oder so
Delphi-Quellcode:
, aber Clear ist schon schöner.
Form1.SQLQuery1.ParamByName('fk_category_id').Value := nil;
Zitat:
Da steht doch genau in der Fehlermeldung drin, was da nicht geht. Oder würdest du auch ein
Delphi-Quellcode:
oder
Form1.SQLQuery1.ParamByName('fk_category_id').AsInteger := 'abc';
Delphi-Quellcode:
veruchen?
Form1.SQLQuery1.ParamByName('fk_category_id').AsString := 123;
Eine weitere Frage ist aber auch: Warum ist der ganze Code in TForm2 drin, obwohl über 50% der Zugriffe auf TForm1 gehen? Das würde doch wohl eher in eine Methode der TForm1 gehören und die Werte z.B. als Parameter übergeben. :angel2: |
AW: LastRowID wie auslesen?
Zitat:
|
AW: LastRowID wie auslesen?
[QUOTE=AlexII;1269947]
Delphi-Quellcode:
Das halte ich nicht für optimal. Die möglichen Werte für
Form1.SQLQuery1.ParamByName('fk_category_id').AsInteger := Integer(CategoryComboBox.Items.Objects[CategoryComboBox.ItemIndex])
Code:
sollten aus der DB kommen und nicht aus Deinem Programm. Das kann gut gehen, dafür muß aber sicher gestellt werden, daß
fk_category_id
Code:
und
fk_category_id
Delphi-Quellcode:
immer gleich sind (für gleiche zugehörige Inhalte).
Integer(CategoryComboBox.Items.Objects[CategoryComboBox.ItemIndex])
Null-Werte würde ich nicht über Parameter, sondern explizit übergeben:
Code:
Gruß
'INSERT INTO tbcategory VALUES(NULL, NULL)'
K-H |
AW: LastRowID wie auslesen?
Jah... da muss man sehr aufpassen, aber ich habe alles soweit logisch durchgespielt, es muss gehen. So lade ich die ComboBoxen:
Delphi-Quellcode:
Auch wenn in der ComboBox was gelöscht wird, kommen die IDs nicht durcheinander.
// Kategorie laden
Form2.CategoryComboBox.Clear; Form2.CategoryComboBox.Items.AddObject(' ', TObject(0)); SQLQuery1.Close; SQLQuery1.SQL.Text := 'SELECT id_tbcategory, category FROM tbcategory'; SQLQuery1.Open; while not SQLQuery1.Eof do begin Form2.CategoryComboBox.Items.AddObject(SQLQuery1.FieldByName('category').AsString, TObject(SQLQuery1.FieldByName('id_tbcategory').AsInteger)); SQLQuery1.Next; end; |
AW: LastRowID wie auslesen?
Zitat:
Statt
SQL-Code:
INSERT INTO tabelle VALUES( NULL, :Wert);
SQL-Code:
INSERT INTO tabelle Wert VALUES(:Wert);
|
AW: LastRowID wie auslesen?
Dann musst Du aber auch die Felder angeben:
Delphi-Quellcode:
INSERT INTO tabelle(Feld1, Feld2) VALUES(:Wert1, :Wert2);
|
AW: LastRowID wie auslesen?
Zitat:
Delphi-Quellcode:
Die MSEgui SQLdb Version schreibt die serverseitig generierten Werte übrigens automatisch in die Feldwerte zurück, entweder mittels "LASTINSERTID" für primary keys oder der "RETURNING" clause im SQL statement für beliebige Felder.
TSQLite3Connection.GetInsertID().
|
AW: LastRowID wie auslesen?
Ich habe ein ähnliches Problem, wenn ich mittels Insert / Post einen Datensatz anlege und RowId des neu angelegten Datensatzes bestimmen möchte:
Code:
Da kommt leider immer nur #0#0#0#0... heraus. Was mache ich falsch?
FDQuery.Insert;
FDQuery.FieldByName( 'Name' ).value := 'Müller'; ... FDQuery.Post; RowId := FDConnection.ExecSQLScalar( 'select top 1 LastRowId() LastRowId from Personen' ); |
AW: LastRowID wie auslesen?
Das sieht nach FireDAC aus, dann versuch mal:
Delphi-Quellcode:
FDConnection.GetLastAutoGenValue('');
|
AW: LastRowID wie auslesen?
Klappt leider nicht :( . NULL ist der Rückgabewert.
|
AW: LastRowID wie auslesen?
Hat denn die Tabelle einen Primärschlüssel, der automatisch hochgezählt wird?
|
AW: LastRowID wie auslesen?
Nein, hat sie nicht. Das Problem ist, dass ich die Datenstruktur nicht so einfach ändern kann, da mit einem alten Programm noch mindestens 7 Monate (parallel über den Datenbankserver) darauf zugegriffen werden muß und das alte Programm äußerst empfindlich auf Änderungen in den Tabellen reagiert :shock: . Deshalb auch der Lösungsansatz über LastRowId() (es handelt sich um den Advantage DataBase Server).
Folgendes funktioniert:
Code:
Nur ich brauche eine Lösung mittels FDQuery.Insert...FDQuery.Post und anschließend die RowId.
cRowId := FDConnection.ExecSQLScalar(
'insert into TableName( Name ) values( ''Müller'' );'+ 'select top 1 LastRowId() LastRowId from TableName' ); Vielleicht habe ich einen Fehler, wenn FDQuery.Post ausgeführt wird (da passiert noch einiges mehr) und dadurch die RowId nicht mehr verfügbar ist... Mal sehen, was ich heute Nacht oder morgen noch hinbekomme 8-) . |
AW: LastRowID wie auslesen?
Zitat:
|
AW: LastRowID wie auslesen?
Zitat:
Code:
qu.sql.text := 'insert into TableName( Name ) values( ''Müller'' );'+
'select LastRowId() from system.iota;'; qu.open; lastid := qu.fields[0].asstring; qu.close; |
AW: LastRowID wie auslesen?
Zitat:
Ja, aber Deine Lösung entspricht fast zu 100% der meinigen von Beitrag 20. Ich habe aber Firedac im Einsatz. Dabei benutze ich TDBNavigator in Verbindung mit TFDQuery und TDataSource zum Navigieren. Und wenn der User dabei auf speichern klickt, kann ich erst wieder beim afterPost-Ereignis eingreifen. Oder gibt es noch eine Lösung, wie ich z.B. die "Speicher-Query" anpassen kann? Viele Grüße Uli |
AW: LastRowID wie auslesen?
Hi Uli,
Zitat:
Ich habe mit FireDAC nicht auf ADS zugegriffen, von daher kann ich die Frage nicht im Allgemeinen beantworten. Du könntest aber evtl eine Ableitung davon machen und den obigen Part hinzufügen. Soweit ich weiß, nutzte Dmitry damals nur pures SQL zum Schreiben der Treiber. |
AW: LastRowID wie auslesen?
Macht nichts. :-D.
Ich habe leider noch nicht herausgefunden. Wie das TFDQuery.Post programmiert ist. In der Query steht ja "nur" eine select-Anweisung. Aber wie wird die Update oder Insert Anweisung von TDFQuery generiert? Ist der Quellcode dazu offengelegt? |
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:23 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