AGB  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen FreePascal FreePascal Datenbankabfrage in Array speichern

Datenbankabfrage in Array speichern

Offene Frage von "BerlinerBaer"
Ein Thema von BerlinerBaer · begonnen am 9. Jun 2017 · letzter Beitrag vom 17. Jul 2017
Antwort Antwort
Foren-Tage 2017
DIE Konferenz für Delphi-Entwickler mit vielen Vorträgen und ganztägigen Workshops, veranstaltet u.A. von der Delphi-PRAXiS und Embarcadero.
21.-23. September 2017 in Hamburg · Mehr Infos unter forentage.de.
BerlinerBaer

Registriert seit: 14. Feb 2017
Ort: Berlin
3 Beiträge
 
FreePascal / Lazarus
 
#1

Datenbankabfrage in Array speichern

  Alt 9. Jun 2017, 18:56
Hallo Freunde des Programmierens,

ich komme gleich zum Punkt.

Wie bekomme ich unterschiedliche Werte einer Tabelle, die jedoch die selbe ID haben, in ein Array gespeichert?
Es geht mir um das gleichzeitige Löschen mehrerer Werte.

Als Beispiel:

Tabelle 1:
id: 1 | kat_id: 1
id: 2 | kat_id: 2
id: 3 | kat_id: 1
id: 4 | kat_id: 1
id: 5 | kat_id: 3
id: 6 | kat_id: 1

Kat_id ist eine Zuordnungs-ID für eine andere Tabelle. Das Ausgeben dieser IDs ist für mich kein Problem. Das Speichern in ein Array jedoch sehr.

In diesem Beispiel sollen nun alle ID's mit der kat_id 1 gelöscht werdenn. Meine Vorüberlegung war es, die DELETE-Funktion während des SELECTes durchzuführen. Nun ja, es kommt die Meldung, dass es Probleme mit der Perfomance gibt. Nun war meine zweite Idee, die zu löschenden IDs in ein Array zu speichern, welche dann gelöscht werden können. Nun meine Fragen.
1. Wie bekomme ich die unterschiedlichen IDs in ein Array?
2. Welches Array wäre besser, ein dynamisches oder statisches Array?
3. Wäre eine for-each-Schreife (wie in php) möglich? Wenn ja, wie?

Hier mir Quellcode:
Code:
procedure TFormMain.PopupMenuItemRechnungLoeschenClick(Sender: TObject);
var
  id, InfoTitel, InfoText : String;
  i : String;
begin
  InfoTitel:='Rechnung löschen?';
  InfoText:='Soll die ausgewählte Rechnung wirklich gelöscht werden?';
  if LVRechnungen.SelCount >= 1 then
    begin
      if QuestionDlg(InfoTitel, InfoText, mtWarning, [mrYes, 'Ja', mrNo, 'Nein'], 0) = mrYes then
        begin
          id:=LVRechnungen.Selected.Caption;
          ZQuery.SQL.Clear;
          ZQuery.Params.Clear;
          ZQuery.SQL.Text:='SELECT ReKatID, ReInhID FROM rechnungen_inhalt WHERE ReKatID='+#39+id+#39+' ORDER BY ReInhID DESC';
          ZQuery.Open;
          while not ZQuery.EOF do
            begin

              i:=ZQuery.FieldByName('ReInhID').AsString;
              ShowMessage(i);

              ZQuery.Next;
            end;
          ZQuery.Close;
          //ZQuery.SQL.Text:='DELETE FROM rechnungen_inhalt WHERE ReKatID='+#39+id+#39;
          //ZQuery.ExecSQL;
          //LVRechnungen.Selected.Delete;
        end;
    end;
end;
Weitere Informationen:
Datenbank-Protokoll: sqlite3
Datenbank-Schnittstelle: ZeosDB (sofern man das als Schnittstelle bezeichnen kann)
Programm: Lazarus IDE v1.6.2

Leider sind meine Kenntnisse noch auf einem relativ geringem Niveau, sodass ich um Hilfe bitten muss.

Über postive Rückmeldungen würde ich mich sehr freuen.

Liebe Grüße
BerlinerBaer

Geändert von BerlinerBaer ( 9. Jun 2017 um 19:01 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
5.602 Beiträge
 
Delphi 7 Personal
 
#2

AW: Datenbankabfrage in Array speichern

  Alt 9. Jun 2017, 20:35
Hallo BerlinerBaer,
willkommen in der Delphi-Praxis.
1) Wenn Du die ReInhId als String zurück gibst empfehle ich Dir eine Stringlist zu nutzen.
2)Wenn Du
Delphi-Quellcode:
 ZQuery.SQL.Text:='SELECT ReKatID, ReInhID FROM rechnungen_inhalt WHERE ReKatID='+#39+id+#39+' ORDER BY ReInhID DESC';
...
ZQuery.SQL.Text:='DELETE FROM rechnungen_inhalt WHERE ReKatID='+#39+id+#39;
ReKatID übergibst um die Daten abzufragen, dann kannst Du auch gleich ein Delete Durchführen.
3) Du solltest Dir gleich angewöhnen Parameter zu nutzen:
Delphi-Quellcode:
ZQuery.SQL.Text:='SELECT ReKatID, ReInhID FROM rechnungen_inhalt WHERE ReKatID=:rekatid ORDER BY ReInhID DESC';
ZQuery.SQL.Parameters.ParameterbyName('rekatid').asString:=id;
(ich kenne die genaue Syntax bei Zeos nicht, bitte überprüfen)

Gruß
K-H
Programme gehorchen nicht Deinen Absichten
sondern Deinen Anweisungen
Do it with Delphi Programming
  Mit Zitat antworten Zitat
Benutzerbild von haentschman
haentschman

Registriert seit: 24. Okt 2006
Ort: Seifhennersdorf / Sachsen
3.649 Beiträge
 
Delphi 10.1 Berlin Professional
 
#3

AW: Datenbankabfrage in Array speichern

  Alt 10. Jun 2017, 06:18
Hallöle...
Zitat:
3. Wäre eine for-each-Schreife (wie in php) möglich? Wenn ja, wie?
http://wiki.freepascal.org/for-in_loop

Ergänzung:
ZQuery.SQL.ParamByName('rekatid').asString := id; ...bei Zeos ist es auch so korrekt. (kürzer)

Nachtrag:
Delphi-Quellcode:
//ZQuery.SQL.Clear; //nicht nötig
//ZQuery.Params.Clear; //nicht nötig
ZQuery.SQL.Text:='SELECT ReKatID, ReInhID FROM rechnungen_inhalt WHERE ReKatID=:id ORDER BY ReInhID DESC';
ZQuery.SQL.ParamByName('rekatid').asString := id;
ZQuery.Open;

Geändert von haentschman (10. Jun 2017 um 07:31 Uhr)
  Mit Zitat antworten Zitat
BerlinerBaer

Registriert seit: 14. Feb 2017
Ort: Berlin
3 Beiträge
 
FreePascal / Lazarus
 
#4

AW: Datenbankabfrage in Array speichern

  Alt 11. Jun 2017, 12:25
Hallo BerlinerBaer,
willkommen in der Delphi-Praxis.
Hallo p80286 (K-H),

vielen Dank für die Begrüßung.

Das Problem jedoch ist folgender, dass ich nicht nur eine, sondern alle mit der selbigen ReKatID löschen möchte. Dazu war mein Beispiel oben etwas verwirrend.

So sollte es aussehen:
Tabelle 1:
ReInhID (auto_inc + Primärer Schlüssel) | ReKatID (Verweis auf eine andere Tabelle 2)
ReInhID: 1 | ReKatID: 1
ReInhID: 2 | ReKatID: 2
ReInhID: 3 | ReKatID: 1
ReInhID: 4 | ReKatID: 1
ReInhID: 5 | ReKatID: 3
ReInhID: 6 | ReKatID: 1

Tabelle 2:
ReKatID: 1
ReKatID: 2
ReKatID: 3
...fortlaufend

Die 2. Tabelle interessiert mich momentan eher weniger, da ich dort nur ein Datensatz löschen muss. Die entsprechende ReKatID hole ich mir aus einer TListView.

2)Wenn Du
Delphi-Quellcode:
 ZQuery.SQL.Text:='SELECT ReKatID, ReInhID FROM rechnungen_inhalt WHERE ReKatID='+#39+id+#39+' ORDER BY ReInhID DESC';
...
ZQuery.SQL.Text:='DELETE FROM rechnungen_inhalt WHERE ReKatID='+#39+id+#39;
ReKatID übergibst um die Daten abzufragen, dann kannst Du auch gleich ein Delete Durchführen.
Wenn ich während der while-Schleife, also während der Abfrage die entsprechenden ReKatIDs der Tabelle lösche, dann löscht er nur eine, wobei mir auch die entsprechende Fehlermeldung nicht gefällt.

Zitat:
Operation cannot be performed on an inactive dataset.

Press ok.....
Ich muss auf jeden Fall die ReInhID's in ein array speichern, sodass diese mittels
Code:
ZQuery.SQL.Text:='DELETE FROM rechnungen_inhalt WHERE ReInhID IN (1, 3, 4, 6)';
gelöscht werden können. Nur daran verzweifel ich irgendwie.

3) Du solltest Dir gleich angewöhnen Parameter zu nutzen
Ja, das wurde mir auch schon gesagt. Nur verstehe ich da nicht so ganz den Sinn. Ob ich es als Parameter oder als var verwende, ist für mich unlogisch. Liegt vielleicht daran, dass ich mir zu wenig mit Pascal und zu sehr mit PHP auskenne.

Zitat von haentschman:
//ZQuery.SQL.Clear; //nicht nötig
//ZQuery.Params.Clear; //nicht nötig
Hallo haentschman,

wieso ist das nicht nötig? Es geht doch hierbei um die Vermeidung eventueller Fehler. Ich benutze SQL.Text und Params nicht nur ein mal im kompletten Quelltext. Mir wurde erklärt, dass das immer eine Prävention zu eventuell auftretenden Fehlern ist.


Liebe Grüße
BerlinerBaer
  Mit Zitat antworten Zitat
Benutzerbild von haentschman
haentschman

Registriert seit: 24. Okt 2006
Ort: Seifhennersdorf / Sachsen
3.649 Beiträge
 
Delphi 10.1 Berlin Professional
 
#5

AW: Datenbankabfrage in Array speichern

  Alt 11. Jun 2017, 12:58
Hallöle...
Zitat:
wieso ist das nicht nötig?
ZQuery.SQL.Clear ...weil mit SQL.Text eine neue Zuweisung gemacht wird. Das SQL wird eh gelöscht...also doppelt gemoppelt. Anders sieht es ausschließlich mit SQL.Add aus. Da mußt du das zurücksetzen.
ZQuery.Params.Clear ...weil mit SQL.Text die Parameter automatisch geleert werden...also doppelt gemoppelt.
Zitat:
Ja, das wurde mir auch schon gesagt. Nur verstehe ich da nicht so ganz den Sinn.
...siehe:
https://de.wikipedia.org/wiki/SQL-Injection
http://docwiki.embarcadero.com/RADSt...agen_verwenden
Zitat:
Mir wurde erklärt, dass das immer eine Prävention zu eventuell auftretenden Fehlern ist.
...probier es doch einfach aus.
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
5.602 Beiträge
 
Delphi 7 Personal
 
#6

AW: Datenbankabfrage in Array speichern

  Alt 11. Jun 2017, 16:04
Das Problem jedoch ist folgender, dass ich nicht nur eine, sondern alle mit der selbigen ReKatID löschen möchte.
mit  delete from tabelle1 where feld1=meinwert; werden alle Einträge aus Tabelle1 entfernt, wo der Inhalt von Feld1 Meinwert ist.
Es sei denn irgendwelche Constraints oder Trigger sind der Meinung, das darf man so nicht.

Wo genau taucht die Fehlermeldung auf?
in Deinem Sourcecode wird nirgendwo eine Löschung durchgeführt.

Zitat von haentschman:
//ZQuery.SQL.Clear; //nicht nötig
//ZQuery.Params.Clear; //nicht nötig
Hallo haentschman,

wieso ist das nicht nötig? Es geht doch hierbei um die Vermeidung eventueller Fehler. Ich benutze SQL.Text und Params nicht nur ein mal im kompletten Quelltext. Mir wurde erklärt, dass das immer eine Prävention zu eventuell auftretenden Fehlern ist.
Jain, das ist notwendig, wenn Du einen bestimmten Inhalt benötigst, Du Dich aber nicht darauf verlassen kannst, daß die Variable den Wert auch wirklich hat.
In diesem Falle wird mit .SQL.Text:='blabla' genau dieses erreicht.
Dein Vorgehen ist kein schwerer Fehler aber überflüssig und bevor sich da eine schlechte Angewohnheit breit macht.
(meiner Meinung nach fällt das weit verbreitete
Delphi-Quellcode:
.SQL.Lines.Clear;
.SQL.Lines.Add('blabla');
.SQL.Lines.Add('blubblub');
in die gleiche Kategorie. Da lieber gleich
Delphi-Quellcode:
.SQL.Text:='blabla'+
     'blubblub';

Gruß
K-H
Programme gehorchen nicht Deinen Absichten
sondern Deinen Anweisungen
Do it with Delphi Programming

Geändert von p80286 (11. Jun 2017 um 16:09 Uhr)
  Mit Zitat antworten Zitat
BerlinerBaer

Registriert seit: 14. Feb 2017
Ort: Berlin
3 Beiträge
 
FreePascal / Lazarus
 
#7

AW: Datenbankabfrage in Array speichern

  Alt 17. Jul 2017, 12:55
Hallo p80286,

ich danke dir für deine Hilfe. Manchmal übersieht man doch das ein oder andere.

Wieso ich nicht selbst auf die Idee gekommen bin, anhand der KategorieID (ReKatID) zu löschen, frage ich mich.

Die Fehlermeldung tauchte auf, als ich den DELETE-Befehl in die Abfrage gesetzt habe.
Das Problem hat sich damit erledigt.

Liebe Grüße
BerlinerBaer
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:39 Uhr.
Powered by vBulletin® Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2017 by Daniel R. Wolf