Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi DBGrid SelectedRows (https://www.delphipraxis.net/158687-dbgrid-selectedrows.html)

-187- 26. Feb 2011 19:18

Datenbank: Firebird • Version: 2 • Zugriff über: Interbase

DBGrid SelectedRows
 
Moin, ich hab ein kleines Problem mit meiner Datenbank. Ich habe ca 50.000 Einträge und möchte jetzt von allen selektierten Einträge ein Feld in einer Stringlist speichern.

Das ganze mache ich so, is aber sehr langsam:

Delphi-Quellcode:
  for i:=0 to DBGrid1.SelectedRows.Count-1 do
  begin
    DBGrid1.DataSource.DataSet.GotoBookmark(Pointer(DBGrid1.SelectedRows.Items[i]));
    ClearList.Add(DBGrid1.DataSource.DataSet.FieldByName('NUMBER').AsString);
  end;
Kann das jemand performanter gestalten?

Sir Rufo 26. Feb 2011 19:26

AW: DBGrid SelectedRows
 
Delphi-Quellcode:
var
  fld : TField;


  fld := DBGrid1.DataSource.DataSet.FieldByName('NUMBER');
  for i:=0 to DBGrid1.SelectedRows.Count-1 do
  begin
    DBGrid1.DataSource.DataSet.GotoBookmark(Pointer(DBGrid1.SelectedRows.Items[i]));
    ClearList.Add(fld.AsString);
  end;

-187- 26. Feb 2011 19:45

AW: DBGrid SelectedRows
 
Hmm wirklich schneller gehts das damit nicht :) Warum auch ?

Edit: Jedes GotoBookmark wird ja im GUI angezeigt. Kann man das irgendwie für diese Dinge "abkoppeln"?

joachimd 26. Feb 2011 19:59

AW: DBGrid SelectedRows
 
Zitat:

Zitat von -187- (Beitrag 1084589)
Jedes GotoBookmark wird ja im GUI angezeigt. Kann man das irgendwie für diese Dinge "abkoppeln"?

DisableControls heisst das Stichwort.

-187- 26. Feb 2011 20:00

AW: DBGrid SelectedRows
 
Und es funktioniert sogar :)

Vielen Dank!

-187- 26. Feb 2011 20:19

AW: DBGrid SelectedRows
 
Hm das war aber nicht alleine die Ursache für meine lame Anwendung. Nachdem ich alle Werte der Clearlist hinzugefügt habe möchte ich für diese Datensätze ein Query ausführen. Momentan mach ich das so:

Delphi-Quellcode:
  for i:=0 to ClearList.Count-1 do
  begin
    IBQuery2.Close;
    IBQuery2.SQL.Clear;
    IBQuery2.SQL.Add(Format('UPDATE %s SET '+ ...
    IBQuery2.Open;
    IBQuery2.Close;
  end;
Ich muss für jeden Datensatz den SQL Command ausführen. Alle Commands adden und am Ende einmal ausführen funktioniert nicht. Das macht die Sache auch ziemlich lahm :/

Bummi 26. Feb 2011 21:36

AW: DBGrid SelectedRows
 
ID's sammeln und ein Update mit
Code:
where ID in (1,2,3,4)
geht nicht in Deinem Fall ?

-187- 26. Feb 2011 21:59

AW: DBGrid SelectedRows
 
Hmm kannte ich ehrlich gesagt nicht :)

Hab's grad mal ausprobiert. Wenn ich 10 Datensätze markiere klappt es, wenn ich jedoch alle Datensätze markiere (3000 Testweise) krieg ich:

Attempt to execute an unprepared dynamic SQL statement.


Kann es sein das es für das Statement eine max Length gibt ?

Bummi 26. Feb 2011 22:03

AW: DBGrid SelectedRows
 
muss ich passen, it ID und Firebird habe ich so gut wie keine Erfahrungen, mit MSSQL-Server bin ich bisher nicht auf derartige Grenzen gestoßen...

-187- 26. Feb 2011 22:06

AW: DBGrid SelectedRows
 
Habs grad rausgefunden. Maximal 1500 Items..

Naja immernoch besser als nichts :)

Edit: Ok, habe jetzt mein Query je auf 1500 Items begrenzt jedoch kommt es mir immernoch langsam vor.

Noch jemand eine Idee? Vielleicht ein ganz anderen Ansatz?

alzaimar 27. Feb 2011 11:18

AW: DBGrid SelectedRows
 
Also den IN-Operator auf diese Weise zu verwenden ist imho keine so gute Idee. Das funktioniert zwar, aber zeigt doch, das deine Anwendung hier keine sinnvolle Operation bietet:

Du lässt Dir z.B. 1.600 Datensätze anzeigen und dann möchtest Du, das ... ein bestimmtes UPDATE auf alle oder einige wenige Datensätze ausgeführt wird?

Gut. Dann mach das doch auch so: Führe einen Button ein "Auf Alle anwenden". Dahinter verbirgt sich dann ein "UPDATE tabelle SET Feld=NeuerWert". Das geht richtig flott und wäre bezüglich Usability der richtige Weg.

Wer einzelne Datensätze auswählen will, kann das mit Bummi's Methode gerne tun. Wer mehr als 1500 Datensätze auswählt, bekommt eine Warnung, das das zu viele seien, oder Du machst das in Paketen à 1500 Records.

Oder (so mach ich das): Ich habe bei solchen GUI-Metaphern (Liste anzeigen, auswählen) immer zwei Buttons: "Alle Auswählen" und "Auswahl entfernen". Wenn alle Datensätze ausgewählt sind, führe das UPDATE ohne IN aus, ansonsten eben mit.

Ich würde aber grundsätzlich meinen, das die Anzeige von so vielen Datensätzen und die Möglichkeit, aus all diesen Datensätzen etwas auszuwählen, bezüglich der Benutzerfreundlichkeit etwas problematisch ist.

-187- 27. Feb 2011 15:38

AW: DBGrid SelectedRows
 
Naja eine Warnung wie "Zuviele Datensätze ausgewählt" kommt mal garnicht in Frage :) Ich habs ja in Pakete á 1500 aufgeteilt. Die Idee mit dem zweiten Button habe ich bereits umgesetzt.

Scheinbar gibt es keine sinvollere Lösung für mein Problem.

jobo 27. Feb 2011 16:09

AW: DBGrid SelectedRows
 
Ich zweifel ja, ob Anwender oder Anwendung einen großen Nutzen bei dieser Funktion haben/bieten. Wer bitte findet sich denn damit zurecht, in 1000en Datensätzen mit Multiselect die richtigen Daten zu finden, auszuwählen, nicht daneben zu klicken und immer schön die [STRNG] Taste festzuhalten?
Aber das war ja nicht die Frage..

2 Vorschläge:
1. Falls es irgendeine Systematik bei der Auswahl der 1000 Datensätze gibt, die sich durch einen Filter ausdrücken lässt, soetwas nutzen und den Filter einer Stored Proc übergeben, die das gefilterte Update durchführt.
(Das würde m.E. vlt auch die Übersichtlichkeit / Transparenz für den Anwender erhöhen, erst Recht, wenn er (Filter-/Selektions-)Gruppen bilden muss, weil es nicht auf einen Schlag geht.)

oder
2. Die Maske so ändern, dass (De-)Selektion satzweise an eine temporäre Tabelle des Users geschickt wird. Die hinzugefügten Sätze könnten evtl sogar in einem 2. Grid angezeigt werden (Dann könnte man, müsste aber nicht, auf die Nutzung/Anzeige der Selected Items verzichten).
Das lässt sich auch mit den genannten Buttons wie Alles Auswählen, Auswahl invertieren , .. kombinieren.
Zum Update wieder eine Prozedur, die auf Basis der temporären Tabelle arbeitet.
Falls es keine user spezifischen, temporären Tabellen gibt in FB, dann halt eine normale mit den Spalten "ID" (Datensatz) und Session- oder USer-id.

hoika 28. Feb 2011 14:19

AW: DBGrid SelectedRows
 
Hallo,

führe deine Schleife in einer Transaktion aus.

Falls es ich um das Update immer der gleichen Tabelle handelt
-> prepared Query


Heiko

-187- 28. Feb 2011 14:31

AW: DBGrid SelectedRows
 
Hmm kannst du das genauer erklären ? Die Tansaktion rufe ich ja erst nach der Schleife mit .Commit auf.


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