![]() |
brauche hilfe beim loeschen eines datensatzes
hallo,
ich arbeite grad an einem projekt mit einer interbase datenbank, mein problem ist eine fehlermeldung, die erscheint wenn ich einen in einer listbox gewaehlten datensatz loeschen moechte sie lautet: im projekt ... ist eine exception in der Klasse EIBInterbaseError aufgetreten. Meldung: 'validation for colum x_x_x,value"xxxnullxxx"'.
Delphi-Quellcode:
sie tritt bei der delete anweisung auf
if FDB.FARceDB.Connected=false then FDB.FARceDB.Connected:=true;
FDB.TR_FARce.StartTransaction; FDB.DS_Options.ParamByName('ID').Value:=Option[ListBoxOptions.ItemIndex].ID; FDB.DS_Options.Active:=true; FDB.DS_Options.delete kann mir jemand sagen worans liegen koennte? ps: ich habe noch keine erfahrungen mit datenbanken Grumble |
Hallo,
ich kann auch nicht behaupten mich auszukennen, aber die Klammersetzung in der 3. Zeile sieht etwas merkwürdig aus. Gruß Minz |
ja, die klammer hatte ich ausversehen geloescht, das ist aber leider nicht das problem :(
Grumble :coder: |
In der Zeile ist noch eine eckige Klammer :mrgreen:
Minz oh ok schon gesehen |
Erklär doch mal bitte was bei dir Option ist?
ist das eine stinknormale Listbox? |
ja es ist eine normale listbox
option ist ein array eines records Grumble :coder: |
weißt ist halt ein bissel schwierig, wenn da nicht steht, was was ist!
Welche Ausdrücke sind Objekte oder andere Sachen oder so, des braucht man schon um durchzusteigen. Options sieht für mich nach einem eigenen Objekt aus? Mit einer Methode ID? was macht die? |
ich versteh schon, wie soll man da auch so schnell durchsehen, also erlaer ich das mal kurz, ich hoffe das dass so ausreichend ist:
FARceDb: TIBDataBase; TR_FARce: TIBTransaction; DS_Options: TIBDataSet; ListBoxOptions: TListBox; Option:array of T'Record'; Das ganze muesste so funktionieren: Das in der listbox gewaehlte item repraesentiert ein record mit einer integer-variable ID. der datensatz DS_Options dessen feld id mit der ID aus der listbox uebereinstimmt wird gewaehlt. dieser soll dann auch geloescht werden. ich muss dazu sagen es ist auch nicht mein code, sondern ein Teil eines alten projektes, dass ich verbessern bzw. zum laufen bringen muss. Grumble :coder: |
Hallo Grumble,
Der Code, den Du da zu bearbeiten hast, bedarf einer Generalüberholung. Ich glaube, Du hast keinen leichten Job, wenn der Rest des Programms von ähnlicher Qualität ist. Ich gehe mal durch: 1. ob eine Verbindung zur Datenbank existiert, sollte auf der Ebene "Löschen" nicht gecheckt werden, das sollte weiter oben passieren, und Buttons entsprechend aktiviert, bzw, deaktiviert werden. 2. Eine Transaktion einfach starten ist dagegen unsicher. Es sollte also zunächst geprüft werden, ob die Transaktion bereits läuft. 3. Zur Verbesserung der Übersicht und zur Erleichterung des Debuggens kann man die ID, nach der gesucht werden soll, in eine lokale Variable einlesen. 4. Um Programmablauffehler zu vermeiden, ist es besser, bei Parametern (und auch bei Feldnamen über FieldByName) mit der entsprechenden Umformung (z.B. AsInteger, AsString etc.) zu arbeiten als mit "Value", also: ParamByName('ID').AsInteger. 5. Das Löschen eines Datensatzes mit einer bestimmten ID lässt sich wesentlich schneller über SQL realisieren, wenn nicht bereits der Cursor einer geöffneten Datensatzmenge direkt darauf steht (das ist bei Dir anscheinend nicht der Fall). Man könnte zum Beispiel eine eigene Routine schreiben, die einen SQL Befehl ausführt:
Delphi-Quellcode:
IBSQL1 ist dabei eine TIBSQL Komponente, deren Transaktion die selbe ist, mit der auch die genutzte Datenmenge arbeitet. Die Löschen Routine sähe dann so aus:
procedure TDM.ExecIBSQL(ASQL: String);
begin with IBSQL1 do try if not Transaction.InTransaction then Transaction.StartTransaction else if Open then Close; SQL.Clear; SQL.Add(ASQL); ExecQuery; Transaction.Commit; except Transaction.Rollback; end; end;
Delphi-Quellcode:
<Tabelle> ist dabei Dein Tabellenname, <Feldname> der Feldname, der Deine ID enthält. Ach ja: falls Du doch datensensitive Komponenten auf der aktuellen Form hast, deren Datenmengen auf oben genannter Transaktion stehen, sind diese nach dem Löschen natürlich leer, da die Transaktion mit Commit geschlossen wurde. Die entsprechenden Datenmengen musst Du dann neu öffnen. Alternativ kann für IBSQL1 auch eine eigene Transaktion definiert werden, die angezeigten Datenmengen bleiben dann bestehen, bekommen aber von dem Löschvorgang erst nach dem nächsten Commit bzw. Rollback etwas mit.
procedure DeleteDataset;
var vID : longint; vSQL : string; begin vID := Option[ListBoxOptions.ItemIndex].ID; vSQL := 'DELETE FROM <Tabelle> WHERE <Feldname>=' + IntToStr(vID); ExecIBSQL(vSQL); end; Ich hoffe, das hilft Dir weiter gruß, harrybo |
Hallo Grumble 8)
Vielleicht hast Du in Deiner Tabelle kein Primärschlüssel... also mehrere gleiche ID’s... darum „weiß“ Deine Datenbank nicht welcher Datensatz soll gelöscht werden. Gehe in BDE und probiere dort zuerst Dir alle Datensätze mit einer bestimmter ID anzuzeigen... z.B. ID = 10: SELECT * FROM Tabelle1 WHRER ID = 10 Bekommst Du mehrere Datensätze als Antwort dann wäre Dein Fehler klar... im übrigen falls eine Anweisung: DELETE FROM Table1 WHRER ID = 10 erfolgreich abgesetzt wird (direkt in BDE) dann würde ich gerne sehen was für ein Fehler (also Fehler Meldung) du bekommst?... (Bin ich BLIND :shock: oder hat noch keiner danach gefragt? :mrgreen: ) Gruß Paul Jr. P.S. Übrigens... wird eine Query zum löschen eines Datensatzes verwendet (also per Query.Delete) musst die Eigenschaft RequestLive = TRUE sein. Abschicken eines Löschbefehl per ExecSQL kann natürlich helfen... beseitig aber nicht bzw. deckt nicht auf die Ursache für Dein Lösch-Misserfolg... was auf Dauer Dich vor folgen-fehler nicht schützen wird... |
Hallo Harrybo 8)
Gewiß, dass von Dir Harrybo ist einwandfrei :idea: , aber da gibst Du mir (glaube ich schon Recht)..., dass Deine Vorgehensweise in dem von mir beschriebenem Fall (kein Primärschüssel) alle Datensätze mit bestimmten ID löschen würde... Da wir leider weiter nicht wissen was für ein Fehler er hat... tappen wir weiter im Dunkel... zumindest ich... Gruß Paul Jr. |
Fehler steht ganz oben im 1. Beitrag, noch vor dem
Quellcode. |
Danke Minz
tja... mein Alter macht sich langsam bemerkbar... :freak: Gruß Paul Jr. |
vielen dank fuer die vielen antworten, ich werd jetzt mal versuchen das umzusetzen.
Grumble :coder: |
Hi Grumble, Paul Jr. und die anderen,
klar, man hätte hier noch mehr vermuten und schreiben können. Wir wissen z.B. auch nicht, was denn in den Select, Update, Delete, Insert Anweisungen des Datasets steht, es gibt hier auch einen Parameter. Dass die ID eindeutig ist, habe ich jetzt mal vorausgesetzt, um nicht bei Adam und Eva zu beginnen. Ich vermute allerdings, dass hier nicht mehrere ID's gefunden werden, sondern die gesuchte ID, falls diese überhaupt einen Wert hat (mal debuggen) nicht in dieser Tabelle existiert (siehe Fehlermeldung: NULL), das meinte Minz wohl auch. Falls die ID doch mehrfach vorkommt, wären natürlich alle entsprechenden Datensätze gelöscht - klar. Ach ja, es müsste im Anschluss natürlich auch dafür gesorgt werden, dass der entsprechende Eintrag aus der StringList (wieso eigentlich StringList und keine datensensitive Komponente) verschwindet. gruß, harrybo |
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:50 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