![]() |
Datenbank: SQLite-3 • Version: 3.8.7 • Zugriff über: ZEOS 7.0.2
ZEOS und Last_Insert nach Insert
Moinsen,
bin grad einwenig am verzweifeln. Ich füge mit folgender Methode einen Datensatz in eine Tabelle ein:
Delphi-Quellcode:
fsql ist dabei eine TZQuery. :) Um nun den Primärschlüssel (autoincrement) zu ermitteln, hab ich in der
inherited Insert;
if (fstate = rsNew) then begin fsql.SQL.Text := 'INSERT INTO actionarea (areaname,areadescr) VALUES(:areaname,:areadescr);'; fsql.ParamByName('areaname').AsString := fname; fsql.ParamByName('areadescr').AsString := fdescr; fsql.ExecSQL; fsql.Connection.Commit; faaid := GetInsertedId; findex := faaid; fstate := rsNone; end; Basisklasse die Methode GetInsertId implementiert:
Delphi-Quellcode:
ftable ist dabei in Feld, das beim erzeugen der abgeleiteten Instanz entsprechend gesetzt wird.
result := -1;
fsql.SQL.Clear; fsql.Params.Clear; fsql.SQL.Text := 'SELECT last_insert_rowid() as last FROM :table;'; fsql.Prepare; fsql.ParamByName('table').AsString := ftable; fsql.Open; if not fsql.Eof then begin fsql.First; result := fsql.FieldByName('last').AsInteger; end; fsql.Close; end; Problem ist nun, das ich genau beim fsql.open eine Exception "SQL logic error or missing database" bekomme. Die Datenbankverbindung ist jedoch da, der Datensatz wird auch brav eingefügt. Ich hab auch die Abfrage "last_insert..." manuell ausgeführt (natürlich den entsprechenden Tabellenamen eingefügt). Da funktioniert das ganze wunderbar. Woran kann das noch liegen ? |
AW: ZEOS und Last_Insert nach Insert
Hallo,
lass das Prepare einfach weg und übergib den Tabellennamen ohne Parameter. |
AW: ZEOS und Last_Insert nach Insert
AFAIK muss man den Tabellennamen überhaupt nicht angeben. Aus der Doku:
Zitat:
|
AW: ZEOS und Last_Insert nach Insert
ok....jetzt tuts (also ohne Parameter und Tabellenname).:shock:
Aber komisch ists trotzdem, das es im SQLiteStudio und im SQLiteBrowser mit Tabellenname direkt funktioniert. Fällt wohl in die Kategorie "ok..muss ich jetzt nicht verstehen" :) Danke euch beiden. |
AW: ZEOS und Last_Insert nach Insert
Man kann Tabellennamen nicht per Parameter übergeben!
Dashier geht nicht:
Delphi-Quellcode:
Per Parameter kann man nur Werte für die Where-Bedingung übergeben, so wie es beim Insert gemacht wurde.
fsql.SQL.Text := 'SELECT last_insert_rowid() as last FROM :table;';
Dashier würde ebenfalls scheitern:
Delphi-Quellcode:
Das Problem ist also nicht die Nutzung des Tabellennamens im Statement überhaupt, sondern die Übergabe des Tabellennamens als Parameter.
inherited Insert;
if (fstate = rsNew) then begin fsql.SQL.Text := 'INSERT INTO :table (areaname,areadescr) VALUES(:areaname,:areadescr);'; fsql.ParamByName('table').AsString := 'actionarea'; fsql.ParamByName('areaname').AsString := fname; fsql.ParamByName('areadescr').AsString := fdescr; fsql.ExecSQL; fsql.Connection.Commit; faaid := GetInsertedId; findex := faaid; fstate := rsNone; end; |
AW: ZEOS und Last_Insert nach Insert
Das ist AsDesigned. Das dürfte bei fast keinem DBMS funktionieren.
Wenn man SQL-Statements parametrisiert verwenden will, führt die Datenbank ein Prepare darauf aus. Kenn es die beteiligten Tabellen nicht, kann das nicht durchgeführt werden da ja die DB nicht weiß was sie überhaupt machen soll. |
AW: ZEOS und Last_Insert nach Insert
Hallo,
Zitat:
|
AW: ZEOS und Last_Insert nach Insert
Wenn ZEOS/SQLite das unterstützen würde, könnte man das insert und das select last_insert_rowid() direkt in einem Rutsch ausführen.
Das würde auch das Risiko vermindern, dass über die gleiche Connection möglicherweise zwischenzeitlich in weiteres insert passiert und die ID verfälscht. Zitat:
![]() |
AW: ZEOS und Last_Insert nach Insert
Ok...danke für die Aufklärung :)
Aber wenns so nicht tut, dann spiel ich halt das Spiel mit Bergen und Propheten :) Über
Code:
sollte das ganze gehen, denk ich. Da besagte Tabelle(n) über AUTOINCREMENT die ID bauen.
SELECT seq FROM sqlite_sequence WHERE (name=:table);
|
AW: ZEOS und Last_Insert nach Insert
Zitat:
Kann es grad nicht ausprobieren, wenn es nicht geht, dann eher so:
Code:
P.S.: Die Variante mit der Code Änderung von Stevie ist natürlich top.
SELECT seq FROM sqlite_sequence ;
Alle die Krücken mit der last insert id sind m.E. immer für Ärger geeignet. Ausnahme bei Verwendung mit einer Sitzung alleine, also für sqlite je nach Einsatzzweck okay. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:34 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-2025 by Thomas Breitkreuz