Mehrere Datensätze löschen

Für Themen zu Datenbanken und Zugriff auf diese. Auch für Datenbankkomponenten.
Luckner
Beiträge: 88
Registriert: Sa 18. Jan 2020, 09:56
OS, Lazarus, FPC: Winux (L 2.2.0 FPC 3.2.2)
CPU-Target: Windows 64-Bit

Mehrere Datensätze löschen

Beitrag von Luckner »

Hallo,

ich versuche einige Datensätze aus einer Tabelle zu lösche. mit den Zeilen darunter funktioniert es auch abe bekomme sofort eine Fehlermeldung, mit der ich nichts anfangen kann. Bitte um Hilfe.

Code: Alles auswählen

  DataModuleArtikel.ZQueryNummerierung.Close;
  DataModuleArtikel.ZQueryNummerierung.SQL.Clear;
  DataModuleArtikel.ZQueryNummerierung.SQL.Add('delete From NUMMERIERUNG WHERE ARTIKELNR = ' + EditArtikelNr.Text);
  DataModuleArtikel.ZQueryNummerierung.Open;

  if DataModuleArtikel.ZQueryNummerierung.RecordCount > 0 then
  begin
      DataModuleArtikel.ZQueryNummerierung.FetchAll;  //Es könnten schon einige Datensätze sein
      DataModuleArtikel.ZQueryNummerierung.First;

     while not DataModuleArtikel.ZQueryNummerierung.EOF do
     begin
         DataModuleArtikel.ZQueryNummerierung.ExecSQL;
     end;
  end;             
Fehlerausgabe: Projekt Etikbase hat Exception-Klasse "Exception" ausgelöst mit der Meldung "Can not open a Resultset in Datei "ZAbstract RODataset.pas in Zeile3528

Habe es schon mit einer For-Schleife versucht, aber mit dem gleichen Ergebnis. Meine Vermutung ist, dass ich irgendwelche Parameter in der TQuery ´deaktivieren muß?

Gruß, Luckner

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6212
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Mehrere Datensätze löschen

Beitrag von af0815 »

Was willst du in der Query ?

Entweder Daten anzeigen -> Dann mit SELECT -> und Open
oder Daten löschen -> dann mit DELETE -> und ExecSQL (oder wie der Befehl bei deinem System heisst)

Du löscht zuerst deiner Query die vermutlich ein SELECT Statement beinhaltet hat, einfach das Statment, fügst statt dessen ein Delete ein und machst dann ein Fetchall, als wäre ein SELECT vorhanden.

Bitte entweder die Query ordentlich konfigurieren (mit Insert, Update und delete Statements) und damit arbeiten oder das ganze richtig aufteilen und nicht alles vermischen. Beim Auto würde ich sagen, du mischt Benzin, Diesel und Salatöl und wunderst dich, warum die Motorkontrolle angeht und der Motor nicht läuft.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Benutzeravatar
gladio
Beiträge: 217
Registriert: Sa 21. Jun 2014, 06:15
OS, Lazarus, FPC: Win10-64 - aktuelle Lazarus/FPC Standard-Edition
CPU-Target: 64Bit
Wohnort: Rügen

Re: Mehrere Datensätze löschen

Beitrag von gladio »

Das Löschen mit Delete in einem SQL-Statemant muß nicht in einer Schleife durchgeführt werden.
Es werden alle Datensätze gelöscht, auf die die Bedingung zutrifft.

f ür

Code: Alles auswählen

..ARTIKELNR = ' + EditArtikelNr.Text);
nutze bitte einen Parameter

Code: Alles auswählen

  DataModuleArtikel.ZQueryNummerierung.Close;
  DataModuleArtikel.ZQueryNummerierung.SQL.Clear;
  DataModuleArtikel.ZQueryNummerierung.SQL.Add('delete From NUMMERIERUNG WHERE ARTIKELNR = :ArtikelNummer);
  
  DataModuleArtikel.ZQueryNummerierung.ParamByName('Artikelnummer').AsString:=EditArtikelNr.Text;
  
  DataModuleArtikel.ZQueryNummerierung.ExecSQL;

Luckner
Beiträge: 88
Registriert: Sa 18. Jan 2020, 09:56
OS, Lazarus, FPC: Winux (L 2.2.0 FPC 3.2.2)
CPU-Target: Windows 64-Bit

Re: Mehrere Datensätze löschen

Beitrag von Luckner »

Hallo gladio,

danke Dir für den Hinweis. Hat sofort funktioniert. Habe die Zeilen:

Code: Alles auswählen

  DataModuleArtikel.ZQueryNummerierung.SQL.Add('delete From NUMMERIERUNG WHERE ARTIKELNR = :ArtikelNummer);
  
   DataModuleArtikel.ZQueryNummerierung.ParamByName('Artikelnummer').AsString:=EditArtikelNr.Text;
durch

Code: Alles auswählen

  DataModuleArtikel.ZQueryNummerierung.SQL.Add('delete From NUMMERIERUNG WHERE ARTIKELNR = ' + QuotedStr(EditArtikelNr.Text)); 
und es funktioniert auch. Sind die beiden Varianten identisch?

Gruß, Andreas

Benutzeravatar
gladio
Beiträge: 217
Registriert: Sa 21. Jun 2014, 06:15
OS, Lazarus, FPC: Win10-64 - aktuelle Lazarus/FPC Standard-Edition
CPU-Target: 64Bit
Wohnort: Rügen

Re: Mehrere Datensätze löschen

Beitrag von gladio »

Wenn in der Artikelnummer keine Anführungszeichen enthalten sind, sollte QuotedStr eigentlich überflüssig sein.
Auch wenn es jetzt so funktioniert, würde ich die Nutzung mit Parameterübergabe bevorzugen.
Und beim Rumprobieren immer schön mit einer Kopie der Datenbank arbeiten.

Luckner
Beiträge: 88
Registriert: Sa 18. Jan 2020, 09:56
OS, Lazarus, FPC: Winux (L 2.2.0 FPC 3.2.2)
CPU-Target: Windows 64-Bit

Re: Mehrere Datensätze löschen

Beitrag von Luckner »

Besteht die Möglichkeit, 1 oder auch mehrere Datensätze auch auf dieser Weiser zu löschen?

Code: Alles auswählen

  DataModuleDokumente1.ZConnectionDokumente.Connect;
  DataModuleDokumente1.ZQueryPositionenTemp_Grid.Close;
  DataModuleDokumente1.ZQueryPositionenTemp_Grid.SQL.Clear;
  DataModuleDokumente1.ZQueryPositionenTemp_Grid.SQL.Add('select ID, ID_BEARBEITER, ARTIKELNR from POSITIONEN_TEMP where ID_BEARBEITER = 1');
  DataModuleDokumente1.ZQueryPositionenTemp_Grid.Open;
  
  DataModuleDokumente1.ZQueryPositionenTemp_Grid.Delete;
  DataModuleDokumente1.ZQueryPositionenTemp_Grid.ExecSQL;
Habe es ausprobiert, jedoch, auch ohne Fehlermeldung, kein Erfolg. Die ZQuery bietet diese Möglichkeit an, aber wie?

Gruß, Luckner

Luckner
Beiträge: 88
Registriert: Sa 18. Jan 2020, 09:56
OS, Lazarus, FPC: Winux (L 2.2.0 FPC 3.2.2)
CPU-Target: Windows 64-Bit

Re: Mehrere Datensätze löschen

Beitrag von Luckner »

Ich bekomme z.Zt. die Datensätze nicht mal durch direkte Anweisung das Löschen hin:

Code: Alles auswählen

  if not DataModuleDokumente1.ZQueryPositionenTemp_Grid.IsEmpty then
  begin
    ShowMessage('Datensatz gefunden');
    DataModuleDokumente1.ZQueryPositionenTemp_Grid.Close;
    DataModuleDokumente1.ZQueryPositionenTemp_Grid.SQL.Clear;
    DataModuleDokumente1.ZQueryPositionenTemp_Grid.SQL.Add('delete from POSITIONEN_TEMP where ID_BEARBEITER = 1');
    DataModuleDokumente1.ZQueryPositionenTemp_Grid.ExecSQL;
Datensatz wird, ohne Fehleranzeige, nicht gelöscht. Auch mit der Parameterangabe:

Code: Alles auswählen

  if not DataModuleDokumente1.ZQueryPositionenTemp_Grid.IsEmpty then
  begin
    ShowMessage('Datensatz gefunden');
    DataModuleDokumente1.ZQueryPositionenTemp_Grid.Close;
    DataModuleDokumente1.ZQueryPositionenTemp_Grid.SQL.Clear;
    DataModuleDokumente1.ZQueryPositionenTemp_Grid.SQL.Add('delete from POSITIONEN_TEMP where BEARBEITER = :bID ');
    DataModuleDokumente1.ZQueryPositionenTemp_Grid.Params.ParamValues['bID'] := 1;
    DataModuleDokumente1.ZQueryPositionenTemp_Grid.ExecSQL;
funktioniert auch nicht.

Gruß, Luckner

Joh
Lazarusforum e. V.
Beiträge: 191
Registriert: Sa 26. Mai 2012, 17:31
OS, Lazarus, FPC: Win 10 (L 2.2.6 x64 FPC 3.2.2)
CPU-Target: 64Bit

Re: Mehrere Datensätze löschen

Beitrag von Joh »

wahrscheinlich wird der Datensatz gelöscht. Aber womöglich vergißt du ein

Code: Alles auswählen

Transaction.Commit;
?
Luckner hat geschrieben:
Fr 1. Dez 2023, 14:08

Code: Alles auswählen

    DataModuleDokumente1.ZQueryPositionenTemp_Grid.SQL.Clear;
    DataModuleDokumente1.ZQueryPositionenTemp_Grid.SQL.Add('delete from POSITIONEN_TEMP where BEARBEITER = :bID ');
Btw: warum schreibt eigentlich jeder

Code: Alles auswählen

.SQL.Clear;
.SQL.Add(...
und nicht

Code: Alles auswählen

.SQL.text := ...
just my two Beer

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6212
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Mehrere Datensätze löschen

Beitrag von af0815 »

Zwischen den Möglichkeiten einen SQL Text zu befüllen, macht je nach System, die Automatik im Hintergrund Mal Unterschiede
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Soner
Beiträge: 623
Registriert: Do 27. Sep 2012, 00:07
OS, Lazarus, FPC: Win10Pro-64Bit, Immer letzte Lazarus Release mit SVN-Fixes
CPU-Target: x86_64-win64
Wohnort: Hamburg

Re: Mehrere Datensätze löschen

Beitrag von Soner »

Du hast doch schon den richtigen Datensatz gefunden, wozu bastelst du noch eine SQL-Anweisung zum löschen? Verwende doch TDataSet.Delete.
Wenn ich deinen Variablennamen(ZQueryPositionenTemp_Grid) anschaue, dann denke ich, dass du es in ein TDBGrid verwendest, wenn ja dann darfst du niemals SQL-Delete verwenden. Du musst in diesem Fall zusätzlich ein temporäres Query erstellen und damit löschen und bei dein Hauptquery Refresh aufrufen. Bei ZEOS-Komponenten kann man das auch ohne zusätzliche Query-Komponente direkt mit TZConnnection.ExecuteDirect erledigen.
Alle Query-Komponenten die du mit Data-Controls verwendest, müssen nur Select-Anweisungen haben, also SQL-Anweisungen mit Rückgabewert.
Du kannst das machen:

Code: Alles auswählen

  if not DataModuleDokumente1.ZQueryPositionenTemp_Grid.IsEmpty then  begin
    ShowMessage('Datensatz gefunden');
    DataModuleDokumente1.ZQueryPositionenTemp_Grid.Delete;
    //falls deine TZQuery die Eigenschaft CachedUpdate=true hat dann mach das:
    // if DataModuleDokumente1.ZQueryPositionenTemp_Grid.UpdatesPending then DataModuleDokumente1.ZQueryPositionenTemp_Grid.ApplyUpdates;
  end;

Ich würde in deiner Stelle das lesen.

Gutes Gelingen.

Joh
Lazarusforum e. V.
Beiträge: 191
Registriert: Sa 26. Mai 2012, 17:31
OS, Lazarus, FPC: Win 10 (L 2.2.6 x64 FPC 3.2.2)
CPU-Target: 64Bit

Re: Mehrere Datensätze löschen

Beitrag von Joh »

Ich befürchte, das Problem liegt tiefer...

Code: Alles auswählen

SQLQuery.Delete;
SQLQuery.ApplyUpdates;
SQLTransaction.CommitRetaining;
was bedeutet das?

oder bei subTables // z.B. alle löschen

Code: Alles auswählen

while not SQLSub.EoF do
begin
  SQLSub.Delete;
  SQLSub.First;
end;
// und letztlich
SQLSub.ApplyUpdates;
SQLTransaction.CommitRetaining;
und das?

eigentlich fehlt (wie immer) die saubere Dokumentation.
Gerade im DB-Bereich gibt es da dann auch noch das Splitting: sqldb vs. zeos
Wie zum Teufel soll man sich da durchfinden?

Wir drehen uns im Kreis: Doku schlecht, Doku Deutsch: -1, Diskussion über das weitere Vorgehen: +2
just my two Beer

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6212
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Mehrere Datensätze löschen

Beitrag von af0815 »

Es gibt kein Splitting, SQLdb ist fpc/Lazarus native.

ZEOS ist ein sehr altes, aber noch immer aktuelles und gut gewartete externe Komponente, die unter Delphi schon gut war. Die ursprüngliche Heimat ist Delphi, schön das auch die Lazaruskompatibilität vorhanden ist. Es ist aber eine externe Komponente, mit eigenen Forum, eigenen Entwicklern und die laufen manchen Entwicklungen in fpc bzw. Lazarus als getriebene hinterher.

Das muss man bei seiner Entscheidung zum DB System brrücksichtigen. Ein Wechsel ist nur mit entsprechenden Aufwand zu machen. Jedes System hat Vorteile und Nachteile. Rosinenpicken und jammern gilt nicht :D
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

charlytango
Beiträge: 844
Registriert: Sa 12. Sep 2015, 12:10
OS, Lazarus, FPC: Laz stable (2.2.6, 3.x)
CPU-Target: Win 32/64, Linux64
Wohnort: Wien

Re: Mehrere Datensätze löschen

Beitrag von charlytango »

af0815 hat geschrieben:
Sa 2. Dez 2023, 08:59
Es ist aber eine externe Komponente, mit eigenen Forum, eigenen Entwicklern und die laufen manchen Entwicklungen in fpc bzw. Lazarus als getriebene hinterher.
Oder auch voraus wenn man sich die unterstützten Datenbanken ansieht (Stichwort MariaDB) :roll:

Luckner
Beiträge: 88
Registriert: Sa 18. Jan 2020, 09:56
OS, Lazarus, FPC: Winux (L 2.2.0 FPC 3.2.2)
CPU-Target: Windows 64-Bit

Re: Mehrere Datensätze löschen

Beitrag von Luckner »

Jetzt habe ich festgestellt, dass es nicht an den Lazarus-Komponnenten liegt, oder überhaupt an der Programmierung. Mit dem Tool Flöame Robin sehe ich, daß in dieser speziellen Tabelle, im Menue des Tools die Option 'delete Row' nicht anwählbar ist. In den anderen Tabellen jedoch schon. Die Tabelle habe ich so estellt:

Code: Alles auswählen

CREATE TABLE POSITIONEN_TEMP
(
  ID integer,
  ID_BEARBEITER smallint,
  POSITIONSNR smallint,
  ANZAHL decimal(7,2),
  ARTIKELNR integer,
  SUCHBEGRIFF varchar(50),
  BESCHREIBUNG blob sub_type 1,
  LISTENPREIS decimal(10,2),
  RABATTPROZENT decimal(5,2),
  EK_PREIS decimal(10,2),
  LIEFERANTENNR integer,
  ARTIKELAUFSCHLAGPROZ decimal(5,2),
  ARTILELAUFSCHLAGBETRAG decimal(10,2),
  ALTERNATIVARTIKELNR integer,
  ARTIKELGRUPPEID smallint,
  VKPREISNETTO decimal(10,2),
  VKPREISNGESAMTNETTO decimal(10,2),
  MWSTPROZENT decimal(5,2),
  MWSTZAHL decimal(7,2),
  VKPREISNGESAMTBRUTTO decimal(10,2)
);

CREATE UNIQUE INDEX IDX_POSITIONEN_TEMP ON POSITIONEN_TEMP (ID);
CREATE INDEX IDX_POSITIONEN_TEMP1 ON POSITIONEN_TEMP (ID_BEARBEITER);
GRANT DELETE, INSERT, REFERENCES, SELECT, UPDATE
 ON POSITIONEN_TEMP TO  SYSDBA WITH GRANT OPTION;
Die anderen Tabellen habe ebenfalls so erstellt und dort kann ich die jede Zeile löschen.

Gruß, Luckner

Luckner
Beiträge: 88
Registriert: Sa 18. Jan 2020, 09:56
OS, Lazarus, FPC: Winux (L 2.2.0 FPC 3.2.2)
CPU-Target: Windows 64-Bit

Re: Mehrere Datensätze löschen

Beitrag von Luckner »

Fehler gefunden. In der ZConnection war 'Autocommit' auf False. Auf True umgestellt und es funktioniert.

Gruß, Luckner

Antworten