Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Einen Datensatz löschen aus SQL sortiertem Datenbestand (https://www.delphipraxis.net/14224-einen-datensatz-loeschen-aus-sql-sortiertem-datenbestand.html)

LuckyStrike4life 5. Jan 2004 07:45


Einen Datensatz löschen aus SQL sortiertem Datenbestand
 
Morgen,
neues Jahr neues (Un)Glück.

Die Überschrift ist vielleicht etwas nichts sagend, daher hier mal eine genaue Erklärung.

Den Inhalt einer Datenbank wird in nem DBGrid ausgegeben. Der Inhalt wird sortiert nach Datum angezeigt, dies ist relevant - haben wir ja schon ne Weile drüber diskutiert.

Nun funktioniert das löschen eines ausgewählten Datensatzes nicht mehr wie früher, d.h. als die Daten im Grid noch nicht sortiert ausgegeben wurden hat es gereicht einen Datensatz anzuklicken, und dann auf den Button zu drücken mit dieser Funktion:
Delphi-Quellcode:
procedure TForm1.BitBtn4Click(Sender: TObject);
begin
maindbtabelle.Delete;
end;
Das geht nun nicht mehr, denn wenn man nun auf den Button klickt ist es egal welcher Datensatz ausgewählt wurde, es wird einfach der (vermutlich) 1. der unsortierten Datenbank gelöscht.

Nun schrieb mir schon ein kluges Köpfchen seine Idee dazu, der auf meine Komponenten angepasste Code sieht so aus:
Delphi-Quellcode:
procedure TForm1.BitBtn4Click(Sender: TObject);
begin
 q_Delete.SQL.Clear;        
  q_Delete.SQL.Add('DELETE FROM mainDB WHERE MainDB=:Id');
  q_Delete.ParamByName('Id').AsInteger := querysort.FieldByName('MainDB').AsInteger;
  q_Delete.ExecSQL; // Wichtig, hier kein Open      
  querySort.Refresh; // Anzeige aktualisieren.
end;
Das Problem dabei war, ich nutze eine DBase Datenbank. Diese hat zwar ein Feld welches eine laufende Nummer enthält, dieses ist aber nicht ansprechbar. Zumindest nicht mit den Mitteln die ich versucht habe.

Das Feld mit dieser (eigentlichen) Indexnummer steht in der Datenbank an der ersten Stelle, die Überschrift der Spalte ist der Name der Datenbank. Zum Beispiel die Datenbank heißt 'Name.dbf' dann heißt die Spalte 'Name'.
Oben im Code heißt die DB 'MainDB', aber leider funktioniert es so nicht :cry: .
Das Programm läßt sich compilieren aber sobald der Button gedrückt wird gibts diese Fehlermeldung
Zitat:

Im Projekt soundso.exe ist ein Exception Fehler der Klasse EDatabaseError aufgetreten. Meldung: 'Querysort: Das Feld 'MainDB' wurde nicht gefunden'. Prozeß wurde angehalten. ...
Kennt jemand einen Weg wie ich dieses 'Indexfeld' ansprechen kann, oder eine ganz andere Lösung für das Problem?
Die Funktion ist wichtig, ich kann diese also nicht weglassen - und das Problem hindert mich extrem an der Fertigstellung *seufz*.

Mario 5. Jan 2004 07:50

Re: Einen Datensatz löschen aus SQL sortiertem Datenbestand
 
Hat Deine Datenbank keinen eindeutigen Primärschlüssel? Den solltest Du für Deine Löschabfrage verwenden können. Ansonsten spendiere Deiner DB doch ein AutoInc Feld. Gibt es so was bei DBase?

r_kerber 5. Jan 2004 07:58

Re: Einen Datensatz löschen aus SQL sortiertem Datenbestand
 
Hallo LuckyStrike4life,

ich denke das Feld MainDB gibt's in Deiner Datenbank nicht. Schau Dir doch mal die genaue Tabellenstruktur an. Wie schaust Du dir die Tabelle eigentlich an? Mit dem Database Desktop? Dann ist die erste Spalte nicht wirklich in der Tabelle enthalten sondern wird zur Anzeige generiert!

LuckyStrike4life 5. Jan 2004 09:23

Re: Einen Datensatz löschen aus SQL sortiertem Datenbestand
 
Zitat:

Zitat von Mario
Hat Deine Datenbank keinen eindeutigen Primärschlüssel? Den solltest Du für Deine Löschabfrage verwenden können. Ansonsten spendiere Deiner DB doch ein AutoInc Feld. Gibt es so was bei DBase?

So richtig anscheinend nicht,
wie gesagt - diese eine Spalte beinhaltet für jede Zeile eine Nummer, läßt sich aber nicht ansprechen.
Wie kann ich der DB ein AutoInc Feld spendieren, es läßt sich leider kein Feld (Spalte) so deklarieren.

Zitat:

Zitat von r_kerber
ich denke das Feld MainDB gibt's in Deiner Datenbank nicht. Schau Dir doch mal die genaue Tabellenstruktur an. Wie schaust Du dir die Tabelle eigentlich an? Mit dem Database Desktop? Dann ist die erste Spalte nicht wirklich in der Tabelle enthalten sondern wird zur Anzeige generiert!

Richtig, normal gehe ich über die Datenbankoberfläche, um mir die Tabellen anzeigen zu lassen.
Aber wenn diese Spalte erst generiert wird beim öffnen, ... dann müssen die Nummern ja doch schon irgendwo vorhanden sein, die in die Spalte für die jeweilige Zeile eingetragen werden.
Hmm...

r_kerber 5. Jan 2004 09:37

Re: Einen Datensatz löschen aus SQL sortiertem Datenbestand
 
Zitat:

Zitat von LuckyStrike4life
Aber wenn diese Spalte erst generiert wird beim öffnen, ... dann müssen die Nummern ja doch schon irgendwo vorhanden sein, die in die Spalte für die jeweilige Zeile eingetragen werden.
Hmm...

Nein sind sie nicht. Diese Spalte eist nicht in der Datenbank-Tabelle.

fkerber 5. Jan 2004 09:37

Re: Einen Datensatz löschen aus SQL sortiertem Datenbestand
 
Hi!

Vielleicht irre ich mich und es ist richtig so (ich habe nämlich prinzipiell keine Ahnung davon), aber folgende Zeile sieht mir komisch aus:

Delphi-Quellcode:
q_Delete.SQL.Add('DELETE FROM mainDB WHERE MainDB=:Id');
                                                 ^^
Wie gesagt, fiel mir nur mal so auf.

Ciao fkerber

LuckyStrike4life 5. Jan 2004 09:48

Re: Einen Datensatz löschen aus SQL sortiertem Datenbestand
 
Zitat:

Zitat von r_kerber
Zitat:

Zitat von LuckyStrike4life
Aber wenn diese Spalte erst generiert wird beim öffnen, ... dann müssen die Nummern ja doch schon irgendwo vorhanden sein, die in die Spalte für die jeweilige Zeile eingetragen werden.
Hmm...

Nein sind sie nicht. Diese Spalte eist nicht in der Datenbank-Tabelle.

Hm.. na gut, aber was für eine Lösung gibt es dann noch?

Zitat:

Zitat von r_kerber
Vielleicht irre ich mich und es ist richtig so (ich habe nämlich prinzipiell keine Ahnung davon), aber folgende Zeile sieht mir komisch aus:

Source:

q_Delete.SQL.Add('DELETE FROM mainDB WHERE MainDB=:Id');
^^



Wie gesagt, fiel mir nur mal so auf.

Ciao fkerber

Was soll da falsch sein?

fkerber 5. Jan 2004 09:57

Re: Einen Datensatz löschen aus SQL sortiertem Datenbestand
 
Hi!

irgendwie hast du die Namen da durcheinander gewürfelt, ich bin fkerber, aber macht ja nix, eigentlioch sind die ^^ bei mir an einer anderen Stelle, bei dem =:, müsste das nicht := heißen?

Ciao fkerber

r_kerber 5. Jan 2004 10:16

Re: Einen Datensatz löschen aus SQL sortiertem Datenbestand
 
Zitat:

Zitat von fkerber
eigentlioch sind die ^^ bei mir an einer anderen Stelle, bei dem =:, müsste das nicht := heißen?

Nö, das ist SQL. :ID ist hier ein Platzhalter für einen Parameter.
Zitat:

Zitat von LuckyStrike4life
Hm.. na gut, aber was für eine Lösung gibt es dann noch?

mach es doch so, wie Du es schon geschriben hast, nur nicht mit der Spalte MainDB sondern mit anderen Spalten Deiner Tabelle (notfalls mit allen).

LuckyStrike4life 6. Jan 2004 07:56

Re: Einen Datensatz löschen aus SQL sortiertem Datenbestand
 
Zitat:

Zitat von r_kerber
mach es doch so, wie Du es schon geschriben hast, nur nicht mit der Spalte MainDB sondern mit anderen Spalten Deiner Tabelle (notfalls mit allen).

Deine Idee mit mehreren Spalten könnte funktionieren.
Wie müsste ich denn dann den Code verändern?

Könnte es auch sein das die Fehlermeldung:
Zitat:

Im Projekt soundso.exe ist ein Exception Fehler der Klasse EDatabaseError aufgetreten. Meldung: 'Querysort: Das Feld 'MainDB' wurde nicht gefunden'. Prozeß wurde angehalten. ...
darauf hinweisen soll, dass der verwendete Query nicht auf die Datenbank schaut - auf die er schauen sollte um das Feld zu finden?

Robert_G 6. Jan 2004 10:33

Re: Einen Datensatz löschen aus SQL sortiertem Datenbestand
 
Moin LuckyStrike.

Ich bezweifle, dass du eine Spalte namens mainDB in deiner Tabelle hast. Deshalb kann deine Abfrage nicht funktionieren.
Hast du keinen Primärschlüssel vergeben oder gibt es wenigstens eine Kombination mehrerer Felder, die eindeutig auf einen Datensatz zeigen?

r_kerber 6. Jan 2004 11:20

Re: Einen Datensatz löschen aus SQL sortiertem Datenbestand
 
Zitat:

Zitat von LuckyStrike4life
Zitat:

Im Projekt soundso.exe ist ein Exception Fehler der Klasse EDatabaseError aufgetreten. Meldung: 'Querysort: Das Feld 'MainDB' wurde nicht gefunden'. Prozeß wurde angehalten. ...
darauf hinweisen soll, dass der verwendete Query nicht auf die Datenbank schaut - auf die er schauen sollte um das Feld zu finden?

Wohl eher nicht. Laß Dich nicht von der ersten Spalte im Datenbank-Desktop verwirren. Die gibt es in Deiner Datenbank nicht. Verwend zum Anzeigen der DB-Tabellen doch besser den Datenbank-Explorer. Hat IMHO den "Vorteil", dass Du dabei angewöhnen mußt, auch für dBase und Paradox-Dateien einen Alias-namen einzurichten, auf den Du dann in Deinem Delphi-Programm mit TDatabase zurückgreifen kannst. Es entfallen somit die festen Pfadeingaben im Programm!

LuckyStrike4life 6. Jan 2004 12:10

Re: Einen Datensatz löschen aus SQL sortiertem Datenbestand
 
Zitat:

Zitat von GeorgeWNewbie
Moin LuckyStrike.

Ich bezweifle, dass du eine Spalte namens mainDB in deiner Tabelle hast. Deshalb kann deine Abfrage nicht funktionieren.
Hast du keinen Primärschlüssel vergeben oder gibt es wenigstens eine Kombination mehrerer Felder, die eindeutig auf einen Datensatz zeigen?

Ja, eine Kombination wäre möglich.
Aber wie muss ich dann den Code verändern? Das geht mir nicht ganz auf.

Zitat:

Zitat von r_kerber
Wohl eher nicht. Laß Dich nicht von der ersten Spalte im Datenbank-Desktop verwirren. Die gibt es in Deiner Datenbank nicht. Verwend zum Anzeigen der DB-Tabellen doch besser den Datenbank-Explorer. Hat IMHO den "Vorteil", dass Du dabei angewöhnen mußt, auch für dBase und Paradox-Dateien einen Alias-namen einzurichten, auf den Du dann in Deinem Delphi-Programm mit TDatabase zurückgreifen kannst. Es entfallen somit die festen Pfadeingaben im Programm!

Ja gut, aber das bringt mich jetzt nicht weiter ... :? .
Wichtig ist - dass ich es schaffe einen bestimmten Datensatz aus dem Programm herraus zu löschen, am Ende werde ich um diese Alias Namen für die DBs vermutlich so oder so nicht herum kommen - da das Programm später nicht von mir gepflegt wird.

r_kerber 6. Jan 2004 12:30

Re: Einen Datensatz löschen aus SQL sortiertem Datenbestand
 
Zitat:

Zitat von LuckyStrike4life
Delphi-Quellcode:
procedure TForm1.BitBtn4Click(Sender: TObject);
begin
  q_Delete.SQL.Clear;        
  q_Delete.SQL.Add('DELETE FROM mainDB WHERE MainDB=:Id');
  q_Delete.ParamByName('Id').AsInteger := querysort.FieldByName('MainDB').AsInteger;
  q_Delete.ExecSQL; // Wichtig, hier kein Open      
  querySort.Refresh; // Anzeige aktualisieren.
end;

Du hast doch schon ganz gut angefangen. Jetzt mußt eben nur Spaltennamen verwenden, die es tatsächlich gibt!

LuckyStrike4life 6. Jan 2004 12:52

Re: Einen Datensatz löschen aus SQL sortiertem Datenbestand
 
Zitat:

Zitat von r_kerber
Zitat:

Zitat von LuckyStrike4life
Delphi-Quellcode:
procedure TForm1.BitBtn4Click(Sender: TObject);
begin
  q_Delete.SQL.Clear;        
  q_Delete.SQL.Add('DELETE FROM mainDB WHERE MainDB=:Id');
  q_Delete.ParamByName('Id').AsInteger := querysort.FieldByName('MainDB').AsInteger;
  q_Delete.ExecSQL; // Wichtig, hier kein Open      
  querySort.Refresh; // Anzeige aktualisieren.
end;

Du hast doch schon ganz gut angefangen. Jetzt mußt eben nur Spaltennamen verwenden, die es tatsächlich gibt!

Okay,
hab ich versucht, hab mal das Feld 'Datum' probiert - aber da kommt die gleiche Fehlermeldung, nur eben das nicht das Feld "MainDB" nicht gefunden wurde, sondern "Datum"
Delphi-Quellcode:
 q_Delete.SQL.Clear;
  q_Delete.SQL.Add('DELETE FROM MainDB WHERE Datum=:Id');
  q_Delete.ParamByName('Id').AsInteger := querysort.FieldByName('Datum').AsInteger;
  q_Delete.ExecSQL; // Wichtig, hier kein Open
  querySort.Refresh; // Anzeige aktualisieren.
Ich verzweifel noch.

LuckyStrike4life 7. Jan 2004 10:41

Re: Einen Datensatz löschen aus SQL sortiertem Datenbestand
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hier mal die Datenbank, vielleicht schaut ihr euch die mal an, z.B. mit Excel. Das Erste Feld zeigt die Spalte an, die ich meinte. Schauts euch mal an, thx.

PS: Da die Endung ".dbf" verboten ist, hab ich noch ".txt" dazu geschrieben. Einfach wegnehmen.

r_kerber 7. Jan 2004 10:54

Re: Einen Datensatz löschen aus SQL sortiertem Datenbestand
 
Zitat:

Zitat von LuckyStrike4life
Okay,
hab ich versucht, hab mal das Feld 'Datum' probiert - aber da kommt die gleiche Fehlermeldung, nur eben das nicht das Feld "MainDB" nicht gefunden wurde, sondern "Datum"
Delphi-Quellcode:
 q_Delete.SQL.Clear;
  q_Delete.SQL.Add('DELETE FROM MainDB WHERE Datum=:Id');
  q_Delete.ParamByName('Id').AsInteger := querysort.FieldByName('Datum').AsInteger;
  q_Delete.ExecSQL; // Wichtig, hier kein Open
  querySort.Refresh; // Anzeige aktualisieren.
Ich verzweifel noch.

Ein Datum ist aber nicht Integer. Versuche doch mal AsDate.

Robert_G 7. Jan 2004 20:54

Re: Einen Datensatz löschen aus SQL sortiertem Datenbestand
 
Hi LuckyStrike.
Wenn du das nächste Mal Beispieldaten schickst, achte bitte auf Datenschutzbestimmungen.
Ich dürfte nicht wissen warum sich ***piep*** einen ***piep*** ausgeliehen hat.

Die einzige eindeutige Kombination dieser Daten wäre Name, Datum, Zweck.
Da man aber nicht sicher sein kann, dass diese Daten niemals doppelt vorkommen würde ich der Tabelle eine fortlaufende Zahl als Primärschlüssel geben.
  • 1 Hugo Ford ...
    2 Egon VW ...
    3 ...

DAnn kannst du das hier nehmen:
Delphi-Quellcode:
  q_Delete.SQL.Text := 'DELETE FROM MainDB WHERE ID = :ID';
  q_Delete.ParamByName('ID').AsInteger := QuerySort.FieldByName('ID').AsInteger;
Du wirst in Zukunft immer wieder auf Probleme stoßen wenn du keine eindeutigen Schlüssel verwendest.
:arrow: Also lieber jetzt als später...

LuckyStrike4life 8. Jan 2004 07:59

Re: Einen Datensatz löschen aus SQL sortiertem Datenbestand
 
Zitat:

Zitat von GeorgeWNewbie
Hi LuckyStrike.
Wenn du das nächste Mal Beispieldaten schickst, achte bitte auf Datenschutzbestimmungen.
Ich dürfte nicht wissen warum sich ***piep*** einen ***piep*** ausgeliehen hat.

Die einzige eindeutige Kombination dieser Daten wäre Name, Datum, Zweck.
Da man aber nicht sicher sein kann, dass diese Daten niemals doppelt vorkommen würde ich der Tabelle eine fortlaufende Zahl als Primärschlüssel geben.
  • 1 Hugo Ford ...
    2 Egon VW ...
    3 ...

DAnn kannst du das hier nehmen:
Delphi-Quellcode:
  q_Delete.SQL.Text := 'DELETE FROM MainDB WHERE ID = :ID';
  q_Delete.ParamByName('ID').AsInteger := QuerySort.FieldByName('ID').AsInteger;
Du wirst in Zukunft immer wieder auf Probleme stoßen wenn du keine eindeutigen Schlüssel verwendest.
:arrow: Also lieber jetzt als später...

Richtig, sowas wie ein Primärschlüssel wäre sehr gut. Dieser müsste aber automatisch erzeugt werden. Und da liegt schon das Problem, es funktioniert nicht so wie es soll.
Es läßt sich keine Spalte als Indexfeld oder Primärfeld deklarieren. Oder mir fehlt zumindest das Wissen wie.

Danke das du dir die Datenbank angeschaut hast und deine Meinung gepostet hast.
Wenn du Ideen hättest, bezüglich eines Primärschlüssels ... sags nur.

LuckyStrike4life 9. Jan 2004 11:05

Re: Einen Datensatz löschen aus SQL sortiertem Datenbestand
 
Hab jetzt mal den Code verändert, und der Datenbank als Test ein Integer Feld spendiert.

Hat den Namen Integ, hab dann Zahlen in die Felder eingetragen 1,2,3,4,5,6,7,8,9,10.

Der Code schaut nun so aus:
Delphi-Quellcode:
q_Delete.SQL.Clear;
  q_Delete.SQL.Add('DELETE FROM "t:eDienstreisebuch\mainDB.dbf" WHERE Integ=:Id');
  q_Delete.ParamByName('Id').AsInteger := querysort.FieldByName('Integ').AsInteger;
  q_Delete.ExecSQL; // Wichtig, hier kein Open
  querySort.Refresh; // Anzeige aktualisieren.
Nun bricht das Programm nicht ab, wenn man auf den Button klickt, der Code läuft auch durch - denn am Ende wird der Query kurz refreshed, aber leider wird gar nichts gelöscht... hm.

Robert_G 9. Jan 2004 11:13

Re: Einen Datensatz löschen aus SQL sortiertem Datenbestand
 
Sind die Daten wirklich nicht weg?
Wenn nicht musst du bei irgendeiner deiner BDE-Kompos (q_Delete oder deren Session) ein Post/Commit ausführen.
Frage2 : Wird bei "querySort.Refresh" wirklich die Abfrage neu ausgeführt?
[Edit]"Integ" ist kein sehr einleuchtender Name für einen Primärschlüssel[/Edit]

LuckyStrike4life 9. Jan 2004 11:22

Re: Einen Datensatz löschen aus SQL sortiertem Datenbestand
 
Zitat:

Zitat von GeorgeWNewbie
Sind die Daten wirklich nicht weg?
Wenn nicht musst du bei irgendeiner deiner BDE-Kompos (q_Delete oder deren Session) ein Post/Commit ausführen.
Frage2 : Wird bei "querySort.Refresh" wirklich die Abfrage neu ausgeführt?
[Edit]"Integ" ist kein sehr einleuchtender Name für einen Primärschlüssel[/Edit]

Hey,
gut das du fragst!
Ich hab mir dann die Datenbank mal über die Datenbankoberfläche angeschaut, und tatsächlich! Es werden die richten Felder gelöscht.

Und es reicht natürlich nicht wenn ich nur den Query refreshe, ich muss auch die Tabelle refreshen, dann gehts.
Also häng ich noch
Delphi-Quellcode:
MainDBtabelle.refresh;
vor den Query refresh.
Dann wirds auch gleich angezeigt.
Soweit, so gut.

Der Name Integ ist natürlich nicht ernst zunehmen, ist nur ein Test.
Aber leider geb ich ja noch die ´Zahlen in dieses Indexfeld selber ein, dass müsste automatisch mit dem Abschicken des Datensatzes geschehen. Da dBase anscheind kein Indexfeld selber verwalten mag, oder ich bin zu blöd das einzustellen.

Robert_G 9. Jan 2004 11:25

Re: Einen Datensatz löschen aus SQL sortiertem Datenbestand
 
Wie wär's mit 'nem neuen Thread "fortlaufender Index in dBase", oder so...

LuckyStrike4life 9. Jan 2004 11:35

Re: Einen Datensatz löschen aus SQL sortiertem Datenbestand
 
Zitat:

Zitat von GeorgeWNewbie
Wie wär's mit 'nem neuen Thread "fortlaufender Index in dBase", oder so...

Okay,
mach ich.
Danke dir.


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:03 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz