Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Löschen in DBGrid funktioniert nicht (https://www.delphipraxis.net/58047-loeschen-dbgrid-funktioniert-nicht.html)

Ati 30. Nov 2005 15:15

Datenbank: Firebird • Version: 1.5 • Zugriff über: Zeos

Löschen in DBGrid funktioniert nicht
 
Hallo zusammen,

in einem Thread hatte ich was gefunden, wie ich über ein DBGrid einen Datensatz löschen kann:
Delphi-Quellcode:
procedure TForm1.btdelClick(Sender: TObject);
begin
  DBGrid1.ReadOnly:=false;
  DBGrid1.DataSource.DataSet.Delete;

end;
Jedoch kommt eine Fehlermeldung wenn ich jetzt den Button drücke "Cannot modify a read-only dataset"??
Habe aber die Eigenschaft meiner Meinung nach auf False gestzt!!

Ati

Luckie 30. Nov 2005 15:18

Re: Löschen in DBGrid funktioniert nicht
 
Du solltest den Datensatz direkt in der Datenbank über einen Query löschen. Das DBGrid ist nur zur Darstellung der Datensätze für den Benutzer gedacht.

Ati 30. Nov 2005 15:33

Re: Löschen in DBGrid funktioniert nicht
 
Zu Deinem Vorschlag sag ich nur ??? Aber nun gut man kann die Suche bemühen.
Trotzdem frag ich mich warum mein Code nicht funktioniert!!

Ati

mikhal 30. Nov 2005 15:39

Re: Löschen in DBGrid funktioniert nicht
 
Existiert für dein DataSet ein SQL-Code für die Delete-Anweisung (Komponente ZUpdateSQL)?

Grüße
Mikhal

Ati 30. Nov 2005 15:46

Re: Löschen in DBGrid funktioniert nicht
 
@mikhal das schreit ja jetzt förmlich nach einer Erklärung!!
Kann Dir nicht folgen...sorry

mikhal 30. Nov 2005 15:56

Re: Löschen in DBGrid funktioniert nicht
 
Auf die Schnelle, weil ich jetzt Feierabend machen will und mich in den allabendlichen Verkehrsstau stürzen will...

Ich weiß nicht, welche DataSet du zugrundelegst, also gehe ich der Einfachheit halber von einer ZQuery aus, sollte aber auch mit ZTable funktionieren.

Zusätzlich benötigst du noch eine ZUpdateSQL, in deren Eigenschaft UpdateSQL das Delete-Statement als SQL-Anweisung eingetragen sein muß. ZQuery besitzt eine Eigenschaft UpdateObject, dort kannst du dein ZUpdateSQL auswählen. Voilà, das war's. Jetzt weiß dein ZQuery, was es mit dem Methodenaufruf Delete anfangen soll.

Grüße
Mikhal

Ati 30. Nov 2005 16:50

Re: Löschen in DBGrid funktioniert nicht
 
Also ich hoffe ich blamier mich nicht wenn ich Luckie und mikhal nicht folgen konnte. Habe das Problem mal so gelöst.
Delphi-Quellcode:
delnum:= qrMain.fieldbyname('Nummer').asString;
delnam:= qrMAin.fieldbyname('NAME').asString;
showmessage(delnum + delnam);
qrMain.sql.clear;
  qrMain.sql.text:='Delete from vim where nummer='+delnum+';';
  qrMain.execSql;
Eigentlich wollte ich in der SQL-Anweisung auch noch den Bezug zum Namen herstellen, jedoch kam da immer eine Fehlermeldung. Dann wollte ich noch das das DBGrid nach dem löschen sofort die aktuellen Datensaätze neu anzeigt, jedoch erhalte ich bei qrMain.refresh; eine Fehlermeldung. Aber sowas kann man doch bestimmt eleganter lösen oder????

Ati

shmia 30. Nov 2005 17:15

Re: Löschen in DBGrid funktioniert nicht
 
Zitat:

Zitat von Ati
Jedoch kommt eine Fehlermeldung wenn ich jetzt den Button drücke "Cannot modify a read-only dataset"??

Du musst grundsätzlich folgende Regeln beachten:
1.) die Tabelle, in der du löschen willst braucht einen Primärschlüssel. Ohne PK geht's nicht !!
2.) du kannst nur in einer Tabelle löschen. In Abfragen, die 2 oder mehr Tabellen verjoinen,
kann nicht gelöscht werden !!
3.) In Abfragen, die GROUP BY oder DISTINCT verwenden kann nicht gelöscht werden !!
Wie lautet denn deine Abfrage oder verwendest du direkt eine Tabelle ?

Sharky 30. Nov 2005 17:22

Re: Löschen in DBGrid funktioniert nicht
 
Hai Ati,

noch als anmerkung zu der Aussage von shmia

Zitat:

Zitat von shmia
1.) die Tabelle, in der du löschen willst braucht einen Primärschlüssel. Ohne PK geht's nicht !!

Dies ist so wenn Du mit der .Delete Methode deines TDataSet arbeiten möchtest. Wenn Du dir mit einem Zusätzlichen TDataSet den Datensatz per SQL-Befehl löschst brauchst Du kein PK.

Was deine Fehlermeldung nach dem .Refresh angeht denke ich mal Das Du folgendes machst:
Delphi-Quellcode:
begin
  with qrMain do
  begin
    Close;
    SQL.Text := 'SELECT * FROM tabelle';
    Open; // Jetzt werden die Daten im DBGrid angezeigt;
    SQL.Text := 'DELETE FROM tabelle WHERE nummer = 1'; // Datensatz wo nummer = 1 ist löschen
    ExecSQL;
    Refresh; // Peng!!! 
  end;
end
Das Refresh kann nicht gehen da Du ja jetzt ein ganz anderes SQL-Statment hast. Du müsstest das ganze also auf zwei Query aufteilen:
Delphi-Quellcode:
begin
  with qrMain do
  begin
    Close;
    SQL.Text := 'SELECT * FROM tabelle';
    Open; // Jetzt werden die Daten im DBGrid angezeigt;
  end;
  with qrDelete do
  begin
    Close;
    SQL.Text := 'DELETE FROM tabelle WHERE nummer = 1'; // Datensatz wo nummer = 1 ist löschen
    ExecSQL;
  end;
  qrMain.Refresh;
end

Ati 30. Nov 2005 21:10

Re: Löschen in DBGrid funktioniert nicht
 
@shmia
Punkt 1+2 habe ich erfüllt. Die Sortierung habe ich (jetzt mal aus dem Kopf) mit qrMain.sort..... gemacht.

@sharky
Genauso wie Du es vermutest hast habe ich es auch gemacht. Jetz mal ne doofe FRage zu Deinem Lösungsansatz. Brauch ich für qrMain und qrDelete zwei Kompo´s auf dem Formular (ich vermute jetzt mal ja).

Jedoch interessiert mich das was mikhal gesagt hat. Habe nämlich keinen Schimmer was ich bei der Update-Komponenten wo eintragen muß.
Außerdem interessiert es mich warum bei der Delete-Anweisung die Kombination aus Nummer und Namen einen Fehler verursacht hat. Was wäre wenn die Nummer zweimal vergeben ist??

Ati

Sharky 1. Dez 2005 05:34

Re: Löschen in DBGrid funktioniert nicht
 
Zitat:

Zitat von Ati
@shmia
Punkt 1+2 habe ich erfüllt. Die Sortierung habe ich (jetzt mal aus dem Kopf) mit qrMain.sort...

Hai Ati,

ein PK (PrimaryKey) hat nichts mit der Sortierung zu tun ;-) Ein PK ist ein Index auf ein Feld der Tabelle. Da ein PK per Definition einmalig ist kann dadurch der zu löschende Datensatz genau identifiziert werden.

Zitat:

... Brauch ich für qrMain und qrDelete zwei Kompo´s auf dem Formular (ich vermute jetzt mal ja).
Ja, für meine Lösung brauchst Du das. Oder zu erzeugst das Query dynamisch zur Laufzeit wenn Du es benötigst.

Zitat:

... Habe nämlich keinen Schimmer was ich bei der Update-Komponenten wo eintragen muß.
Bei der Zeos-Version von Dir blicke ich auch noch nicht so ganz durch. Mir ist nämlich noch nicht klar wie ich dort mit Parametern arbeiten kann :oops:

Zitat:

Außerdem interessiert es mich warum bei der Delete-Anweisung die Kombination aus Nummer und Namen einen Fehler verursacht hat. Was wäre wenn die Nummer zweimal vergeben ist??
In deinem Code oben hast Du ja keine Kombination aus Nummer und Name verwendet.
Wenn im Feld "Nummer" zweimal der selbe Wert steht würden beide Datensätze gelöscht werden. Ganau darum legt man auf solch ein "ID-Feld" einen PK und lässt den Wert dafür über einen Generator vergeben oder macht es per AutoInc. Dadurch wird sichergestellt das nie zwei Datensätze den gleichen Wert in dem Feld haben.

mikhal 1. Dez 2005 06:57

Re: Löschen in DBGrid funktioniert nicht
 
Also, noch mal zum Mitschreiben: Du packst eine ZQuery, ein ZUpdateSQL und ein Datasource (Registerkarte Datenzugriff) auf deine Form. In ObjectInspector suchst du bei ZQuery1 nach der Eigenschaft UpdateObject. Hier klappst du enfach mal die Combobox auf, als Ergebnis solltest du dein ZUpdateSQL finden und auswählen. Damit ist das ZUpdateSQL mit deiner ZQuery verbunden. Des weiteren wählst du für dein DataSource im OI unter DataSet das ZQuery aus. Diese DataSource trägst du in deinem DBGrid als DataSource im OI ein.

Im OI trägst du dann in der Eigenschaft SQL deiner ZQuery das Select-Statement ein, das dir dein Grid füllen soll. Weiter im OI trägst du in der Eigenschaft DeleteSQL deiner ZUpdateSQL das oben bereits verwandte Delete-Statement ein. Du kannst hier auch wie gewohnt Parameter verwenden, die Parameter mußt du dann in der Eigenschaft Parameters genauer definieren (nachdem sie in den Statements eingetragen wurden).

Des weiteren kannst du in InsertSQL das Insert-Statement eintragen, das du einsetzen möchtest, bzw. das Update-Statement in der Eigenschaft ModifySQL.

Wenn du alle SQL-Eigenschaften im ZUpdateSQL gesetzt hast, kannst du wie gewohnt mit den Methoden Edit, Append, Insert und Delete arbeiten.

Ich hoffe, daß es jetzt verständlicher geworden ist.

Grüße
Mikhal

Sharky 1. Dez 2005 07:07

Re: Löschen in DBGrid funktioniert nicht
 
Hai Mikhal,

so hätte ich es ja auch gedacht. Aber bei den Zeos 5.5.0 kann ich im ZZUpDateSQL zwar einen SQL-Befehl zum löschen angeben
SQL-Code:
DELETE FROM tabelle WHERE nummer = :pnummer
Aber ich kann im OI keine Parameter angeben. Wenn ich ohne die Angabe von Parametern ParamCheck auf True stelle kommt sofort das der Parameter pnummer nicht vorhanden ist. Entweder liegt das jetzt an der Kombination Zeos 5.5 und Delphi 3 oder an etwas anderem :oops:

Ich arbeite eigentlich nicht mit Delphi3, ich habe mir das nur schnell aufgebaut um Ati helfen zu können. Mit D2005 und der aktuelle Zeos-Version würde es so gehen wie von Dir beschrieben.

mikhal 1. Dez 2005 07:10

Re: Löschen in DBGrid funktioniert nicht
 
Leider kann ich nur von der Konstellation D7 und ZEOS 6.5.1 alpha vom 13.10.2005 ausgehen, da ich keine andere Konstellation zur Verfügung habe.

Grüße
Mikhal

Ati 1. Dez 2005 07:23

Re: Löschen in DBGrid funktioniert nicht
 
Liste der Anhänge anzeigen (Anzahl: 1)
@mikhal
das Prinzip hatte ich erkannt, nur die Umsetzung klappte nicht. Gott sei Dank hatte Sharky auch Probleme mit dem Umsetzen, sonst hätte ich wieder an mir gezweifelt!!

@Sharky
Meine Delete-Anweisung sah vorher so aus:
Delphi-Quellcode:
qrMain.sql.text:='Delete from vim where nummer='+delnum+' AND name='+delnam+';';
Danach kam eine Fehlermeldung wie im Anhang!!!!

Aber sei es drum. Ich weiß ja das man ein ID-Feld gebrauchen sollte. Jetzt hatte ich hier im Forum einen Thread gefunden das ein ID-Feld, welches automatisch befüllt wird, bei Firebird nur mit einem Trigger zu bewerkstelligen sei. Stimmt das???

Sharky 1. Dez 2005 07:31

Re: Löschen in DBGrid funktioniert nicht
 
Hai Ati,

versuche mal in deinem SQL-Befehl ... AND name = " + QuotedStr(delname); ... zu verwenden.

Wegen der ID in FireBird mache aber bitte einen neuen Thread auf. Sonst blickt bald niemand mehr durch ;-)

Ati 1. Dez 2005 07:41

Re: Löschen in DBGrid funktioniert nicht
 
Zitat:

versuche mal in deinem SQL-Befehl ... AND name = " + QuotedStr(delname); ... zu verwenden
Klappt!!

Zitat:

Wegen der ID in FireBird mache aber bitte einen neuen Thread auf. Sonst blickt bald niemand mehr durch
Wollte ich eigentlich auch. Zumal ich erst selber was versuchen möchte bevor ich andere nerve.

Danke
Ati

rainer4you 1. Dez 2005 11:51

Re: Löschen in DBGrid funktioniert nicht
 
Im DBGrid kann man direkt löschen wenn:

nur auf eine Tabelle zugegriffen wird
die Datenbank im Editiermodus ist

dann einfach den Datensatz markieren, Strg+Entf drücken.

Du kannst die Datenbank nachträglich nur in den read/write Modus setzen wenn
active:= false;
connectionString:= 'bla,bla,read/write'
active:= true;

mfg, silence


Alle Zeitangaben in WEZ +1. Es ist jetzt 14: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