Entwickler-Ecke
Datenbanken - Begrenzte SQL Abfrage
Procedure - Fr 02.12.05 11:11
Titel: Begrenzte SQL Abfrage
hi leutz,
und zwar hab ich mal folgende frage:
wenn ich aus einer tabelle ein select statement mache, wo ca 1000 datensätze zurückkommen, möchte ich dem benutzer die möglichkeit geben, eine begrenzung zu geben, z.b. top 20!
wie kann ich das ins select statement einbinden?
mfg matthias
Stefan.Buchholtz - Fr 02.12.05 11:20
Das ist nicht Teil des ANSI-SQL Standards. Einige Datenbanken haben die Möglichkeit, die Anzahl der zurückgelieferten Datensätze einzuschränken, aber das macht jede anders.
MySQL hat z.B. die Limit-Klausel, das sieht so aus:
SQL-Anweisung
1: 2: 3:
| SELECT * FROM tabelle LIMIT 20 |
Bei Oracle geht es über die Pseudospalte ROWNUM:
SQL-Anweisung
1: 2: 3:
| SELECT * FROM tabelle WHERE ROWNUM <= 20 |
Stefan
jasocul - Fr 02.12.05 11:25
Ich rate davon ab. Eine Begrenzung der Datensätze mit solchen Bedingungen kannst du für programm-interne Zwecke verwenden.
Bei der Visualisierung kann es zu merkwürdigen Ergebnissen kommen.
Wenn du zum Beispiel ein "order by" in deinem Statement hast, kann es passieren, dass erst 20 Datensätze genommen werden und dann das Ergebnis sortiert wird. Normalerweise will man das aber umgekehrt haben. Aus einer sortierten Menge die ersten 20 Datensätze. Ich hoffe die Konsequenzen sind klar.
Stefan.Buchholtz - Fr 02.12.05 11:35
jasocul hat folgendes geschrieben: |
Ich rate davon ab. Eine Begrenzung der Datensätze mit solchen Bedingungen kannst du für programm-interne Zwecke verwenden.
Bei der Visualisierung kann es zu merkwürdigen Ergebnissen kommen.
Wenn du zum Beispiel ein "order by" in deinem Statement hast, kann es passieren, dass erst 20 Datensätze genommen werden und dann das Ergebnis sortiert wird. Normalerweise will man das aber umgekehrt haben. Aus einer sortierten Menge die ersten 20 Datensätze. Ich hoffe die Konsequenzen sind klar. |
Um das Problem kommt man aber herum: MySQL z.B. sortiert grundsätzlich erst und wertet dann die Limit-Klausel aus. Bei Oracle muss man möglicherweise mit einer Unterabfrage arbeiten:
SQL-Anweisung
1: 2: 3: 4: 5:
| SELECT * FROM (SELECT * FROM tabelle ORDER BY ...) WHERE ROWNUM <= 20 |
Trotzdem ist der Sinn begrenzt: Normalerweise werden sowieso nur die Datensätze vom Server übertragen, die das Programm auch anfordert. Eine Query, die 1000 Datensätze liefert ist daher nicht grundsätzlich langsamer als eine, die nur 20 zurückgibt. (Eine richtige Datenbank vorausgesetzt, ich rede hier nicht von Spielzeug wie Paradox-Tabellen o.ä.)
Stefan
Procedure - Fr 02.12.05 11:50
hm, wenn das net so toll is, wie kann ich sowas dann besser realisieren???
ist kein spielzeug, sondern ne oracle!
mfg matthias
noidic - Fr 02.12.05 12:11
Was ist denn der konkrete Anwendungsfall?
Normalerweise sollte man dem Benutzer immer alle Daten zur Verfügung stellen, die er angefordert hat.
Wenn der Benutzer aber nur eine Teilmenge sehen will, wird es ein Kriterium geben, aufgrund dessen er seine Auswahl trifft.
Wenn die tatsächlich nur die Anzahl der Datensätze beschränkt werden soll, kann man die Datensätze aus dem Query in ein ClientDataset übertragen und nach n Datensätzen stoppen. Oder halt die von Stefan beschriebene Methode benutzen.
jasocul - Fr 02.12.05 12:13
Eine Möglichkeit hat Stefan dir ja gezeigt.
Ich hatte das Phänomen mit der Oracle 8.0.5! Mit Spielzeug hat das also nichts zu tun.
Wenn du vernünftige Komponenten einsetzt, benötigst du diese Einschränkung nicht. Du darfst nur kein FetchAll machen. Dann werden die Daten sowieso in kleinen Häppchen an den Client übergeben. Ich glaube, der Standard sind 25 Datensätze.
noidic - Fr 02.12.05 12:18
Wenn man das Fetchall weglässt, werden soviele Daten geholt, wie der Client zur Anzeige anfordert, also z.B. wieviele Zeilen im Grid angezeigt werden.
jasocul - Fr 02.12.05 12:23
Das ist klar. Wenn mehr als 25 DS gebraucht werden, werden weitere Blöcke dazu genommen. Ich meine aber, dass das immer 25er Blöcke sind. Kann mich aber auch irren.
Stefan.Buchholtz - Fr 02.12.05 12:33
jasocul hat folgendes geschrieben: |
Das ist klar. Wenn mehr als 25 DS gebraucht werden, werden weitere Blöcke dazu genommen. Ich meine aber, dass das immer 25er Blöcke sind. Kann mich aber auch irren. |
Das kann vom Client eingestellt werden. Wenn man die BDE verwendet, ist das der Parameter ROWSET SIZE (default auf 20). Bei den DOA-Komponenten geht es mit dem Property ReadBuffer der TOracleQuery (default auf 25).
Stefan
jasocul - Fr 02.12.05 12:40
Stefan.Buchholtz hat folgendes geschrieben: |
Bei den DOA-Komponenten geht es mit dem Property ReadBuffer der TOracleQuery (default auf 25). |
deshalb 25 bei mir. :mrgreen:
Stefan.Buchholtz - Fr 02.12.05 12:42
jasocul hat folgendes geschrieben: |
Stefan.Buchholtz hat folgendes geschrieben: | Bei den DOA-Komponenten geht es mit dem Property ReadBuffer der TOracleQuery (default auf 25). |
deshalb 25 bei mir. :mrgreen: |
Bei mir auch 8)
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!