Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Setze den Cursor dorthin wo... (https://www.delphipraxis.net/182938-setze-den-cursor-dorthin-wo.html)

Der schöne Günther 27. Nov 2014 18:24

Datenbank: Sybase Advantage • Version: 11.10 • Zugriff über: ACE / FireDAC

Setze den Cursor dorthin wo...
 
Das ist wieder eine Idiotenfrage:

Ein
Delphi-Quellcode:
TDataSource
hat einen Cursor den ich lustig bewegen kann. Die Daten stammen aus einem
Delphi-Quellcode:
TDataSet
.

Beispielhafte Query: SELECT ZEITPUNKT, MESSWERT FROM myTable

Sagen wir, mein Resultset ist 1.000.000 Einträge groß. Die Zugriffsschicht hat für meine DBGrid-Anzeige nur die ersten 100 Records geladen. Scrolle ich weiter herunter, werden dynamisch neue Päckchen nachgeladen. Bei FireDAC kann ich bspw. detailliert einstellen, wieviele, wann, usw.


Meine Frage: Ich möchte jetzt an den 35. Mai 2008 springen. Kann ich den "Cursor" irgendwie dahin bewegen?
  • Würde ich den Cursor in meiner Applikation immer eins weiterschieben und schauen ob ich da bin? Nein, das dauert garantiert ewig.
  • Setze ich eine neue Query ab die mir alles "ab" dem 35. Mai ausgibt? Nein, denn dann kann ich nicht mehr "hochscrollen" und die Dinge vor dem 35. Mai sehen.

Was muss ich tun damit das DBMS mir sagt "Oh, was du suchst ist in deinem Resultset das ich noch für dich vorhalte an Position 54321. Hier ist Record 54321 und die nächsten 50 Einträge. Wenn du mehr wissen willst, frag nur weiter."

hathor 27. Nov 2014 18:58

AW: Setze den Cursor dorthin wo...
 
35. Mai 2008
Du solltest mal den Händler (Deiner Drogen) wechseln!

Bernhard Geyer 27. Nov 2014 19:40

AW: Setze den Cursor dorthin wo...
 
Es gibt einen RecordNo. Der ist aber ehr DB-Interner Natur.

Für deinen Fall würde ich eher so vorgehen:

Du willst 31 Mai. Dann lade alle Daten vom 30. Mai - 1 Juni.
Scrollt der User dann Richtung Ende 1. Juni, lade den 2 Juni.
Das alles am besten ohne DB-Sensitive Controls.

Wie man so schön sagt: Niemand will durch 1 Mio. Datensätze sehen. Und der Admin wäre auch froh wenn du nicht 1. Mio Datensätze übers Netz bewegen würdest.
Und die Angabe "ich lade immer ja nur Häpchenweise" bringt den DB-Admin zur Weißglut. Denn deine 1 Mio. Datensätze gehen zwar nicht (gleich) übers Netz, aber der DB-Server muss dafür sorgen das diese 1 Mio. Datensätze entsprechende dem Abfragezeitpunkt gültig bereitstehen (also Löschaktion oder Inserts nicht auf diese 1 Mio. Datensätze wirken).

humbuck 27. Nov 2014 20:10

AW: Setze den Cursor dorthin wo...
 
Naja, wenn du wirklich nach dem 35. Mai suchst, wirste sicherlich verdammt lange und erfolglos suchen müssen.

Solltest du jedoch nach einem realen Datum suchen wollen UND Daten-sensitive Controls verwenden, kannst du dies ja mit der folgenden Funktion versuchen:

function Locate(const KeyFields: string; const KeyValues: Variant; Options: TLocateOptions): Boolean; virtual;

Locate setzt die Cursor-Pos auf den angegeb. Datensatz und von dort kannste dann munter vor- und zurückblättern

zum Bleifisch:

Delphi-Quellcode:
DBGrid1.DataSource.DataSet.DisableControls;
DBGrid1.DataSource.DataSet.Locate('Datum','25.05.2008', [loCaseInsensitive])
DBGrid1.DataSource.DataSet.EnableControls;
Die Suche dauert bei einer Million Datensätzen schlechthin vergleichsweise lange und belastet immer den SQL-Server... ist unvermeidlich...

Der schöne Günther 27. Nov 2014 20:25

AW: Setze den Cursor dorthin wo...
 
Zitat:

Zitat von Bernhard Geyer (Beitrag 1281397)
Und die Angabe "ich lade immer ja nur Häpchenweise" bringt den DB-Admin zur Weißglut. Denn deine 1 Mio. Datensätze gehen zwar nicht (gleich) übers Netz, aber der DB-Server muss dafür sorgen das diese 1 Mio. Datensätze entsprechende dem Abfragezeitpunkt gültig bereitstehen (also Löschaktion oder Inserts nicht auf diese 1 Mio. Datensätze wirken).

Das sehe ich ein. Aber in diesem Fall ist das ok.



Zitat:

Zitat von humbuck (Beitrag 1281398)
kannst du dies ja mit der folgenden Funktion versuchen:

function Locate(const KeyFields: string; const KeyValues: Variant; Options: TLocateOptions): Boolean; virtual;

Danke! Das war genau was ich wollte. In meinem konkreten Fall habe ich dadurch nichts gewonnen denn FireDAC ist nach wie vor genauso langsam, die ACE-Komponenten von Sybase schaffen das in Millisekunden, FireDAC braucht mehrere Sekunden. Da liegt wohl die Schuld bei FireDAC. :|

humbuck 27. Nov 2014 21:39

AW: Setze den Cursor dorthin wo...
 
wenn du zwingend einen zeitlichen Vorteil benötigst, solltest du sicherlich eine andere Verbindungsschicht einsetzen.

Aber noch mal zu deinem Query:
Zitat:

Beispielhafte Query: SELECT ZEITPUNKT, MESSWERT FROM myTable
Es besteht natürlich auch noch die Möglichkeit, die Datenmenge vom SQL-Server einzugrenzen. Das macht das Paket, das über ein Netzwerk versendet wird deutlich schneller:

Query: SELECT ZEITPUNKT, MESSWERT FROM myTable WHERE ZEITPUNKT BETWEEN '23.04.2014' AND '26.05.2014'
Wenn du die Filter-Funktion deiner Datenkomponente verwendest, musst du allerdings auf BEWTEEN verzichten. Alternativ kannste aber auch logische Vergleichsoperatoren verwenden:
ZEITPUNKT >= '23.04.2014' AND ZEITPUNKT < '27.05.2014'

Das ganze ist immer davon abhängig, wie viele Messungen pro Tag durchgeführt werden. Ggf. musst du dann auch kürzere Intervalle selektieren und die Uhrzeit mit ins Spiel bringen, falls möglich...

p80286 27. Nov 2014 22:31

AW: Setze den Cursor dorthin wo...
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1281392)
Was muss ich tun damit das DBMS mir sagt "Oh, was du suchst ist in deinem Resultset das ich noch für dich vorhalte an Position 54321. Hier ist Record 54321 und die nächsten 50 Einträge. Wenn du mehr wissen willst, frag nur weiter."

SQL-Code:
 select Zeitpunkt,messwert top=50 from table order by zeitpunkt
Je nachdem was für einen SQLdialekt Deine DB spricht erhältst Du die ersten 50 Sätze mit top= oder max oder.. (bei einigen leider nicht)

Gruß
K-H

Der schöne Günther 28. Nov 2014 09:27

AW: Setze den Cursor dorthin wo...
 
Nein, genau das wollte ich ja nicht: Eine neue Query absetzen die mir ein neues Resulset ergibt. Ich wollte im bestehenden wohin.

Die vorgeschlagene
Delphi-Quellcode:
Locate(..)
-Methode ist genau, was ich wollte.

Dejan Vu 28. Nov 2014 13:45

AW: Setze den Cursor dorthin wo...
 
Zitat:

Zitat von Bernhard Geyer (Beitrag 1281397)
Und die Angabe "ich lade immer ja nur Häpchenweise" bringt den DB-Admin zur Weißglut. Denn deine 1 Mio. Datensätze gehen zwar nicht (gleich) übers Netz, aber der DB-Server muss dafür sorgen das diese 1 Mio. Datensätze entsprechende dem Abfragezeitpunkt gültig bereitstehen (also Löschaktion oder Inserts nicht auf diese 1 Mio. Datensätze wirken).

Also nee, mittlerweile nicht mehr. Stichwort: Paging Funktionen.
http://en.wikipedia.org/wiki/Select_(SQL) weiter unten bei 'Result limits'
Ist zwar irgendwie auch ein Zugeständnis an die "Ich will alles und immer", aber die Server sind mittlerweile soweit. Wenn sich die Daten mittlerweile ändern, Pech für den Betrachter.

Und, ja: Wenn es keinen Index auf der Ordnungspalte gibt, kotzt der Admin und die Serverprovider reiben sich die Hände, weil noch mehr RAM her muss. Na und der Anwender wartet sich einen Wolf.

Was ganz schlimm ist, und das meinte Bernhard: Wenn ein Provider noch Cursor für das Paging verwendet. Tipp: Schau mal, was der Provider zu deinem SQL-Dings schickt.


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