[ORACLE] PL/SQL Abfrage

Peter Parker

Mitglied
Hallo,

ich habe ein VB6 Client, der auf meinem Server eine C Funktion aufruft. Diese C Funktion startet eine SQL Abfrage an eine ORACLE DB und liest die gewünschten Daten aus. Dannach wird die Ergebnismenge durch einen Loop in eine Ergebnistabelle gefüllt und an den Client das OK zurück gegeben. (Das ganze funktioniert mit PL/SQL und dem Cursur Konzept).

Nachdem der Client das OK erhalten hat, fragt er die Ergebnismenge in der Tabelle ab und stellt das Ergebnis dar.

Problem: Bei der Fülle von Daten, benötige ich eine Möglichkeit, wenigstens ein paar Teildaten z.B. die ersten 100 Treffer anzuzeigen, bis die Abfrage vollständig abgearbeitet ist. Damit ich mit diesem Teilergebnis schon arbeiten kann.

Ich habe gedacht ich könnte ggf. die Daten nicht in die Ergebnistabelle Loopen, sondern die ersten 100 gleich an den Client senden.
Ich habe versucht das Cursor Konzept anzuwenden, aber hierbei muss ja auch zuerst das ganze Ergebniss fest stehen.
Aus der Abfrage selber kann ich ja keine Teilergebnisse ausziehen?

Vielleicht kennt jemand ne Lösung?
Danke!
 
Also, ich weis nicht ob ich ganz verstanden habe wo genau nun dein Problem liegt.
Wenn du schnell eine Antwort von Oracle haben möchtest, beispielsweise die ersten 100
Sätze, dann kannst du beim SELECT mit HINTS arbeiten:

Code:
SELECT /*+ FIRST_ROWS(100) */ employee_id, last_name, salary, job_id
  FROM employees
  WHERE department_id = 20;

Hierdurch wird die Antwortzeit für die ersten 100 Sätze optimiert.
Wie du diese nun mit deinem C Programm an den Client schickst kann ich nicht beurteilen,
wenn du es jedoch mit einem CURSOR machst, dann kannst du das C Programm auch
gleich weglassen.
 
Danke.

Bei dem Cursur Konzept habe ich doch aber das Problem, daß sich der Cursur auf der Ergebnissmenge der gesamten Abfrage sich bewegt. Das heißt, die SQL Abfrage liefert mir als gesamtes Ergebnis 10.000 Datensätze. Der Cursur bewegt sich dann auf diesen 10.000. Ich möchte aber nicht warten bis alle 10.000 Datensätze da sind, sondern zuerst mal 100 und dann wenn der Cursur bei dem 100ten Datensatz ist, soll er am besten die nächsten 100 (100 - 199) abfragen.
Geht das?
 
Bau dir nen Zähler ein

Declare

//Cursor holt alle Daten...

Cursor ...
select ...
c_... get_.. %ROWTYPE;

S_CNT number := 0;

open..
loop..

S_CNT := S_CNT + 1;

if S_CNT <= 100 then

//Deine Verarbeitung


else

//Weitere Verarbeitung,

S_CNT := 0;

end if;



So verarbeitest du erst die ersten 100 DS, anschließend kannst du im else Bereich prüfen. Wenn die Prüfung nicht erfolgreich ist, setzt du S_CNT wieder auf 0 und die
nächsten 100 DS werden verarbeitet.

Mfg
 
Ja, über den Hint /*+ FIRST_ROWS(100) */, wie ich oben schon geschrieben habe. Oracle optimiert die Antwortzeit der ersten 100 Zeilen, d.h. zu bekommst deinen Cursor zurück, sobald die ersten 100 Zeilen zur Verfügung stehen.

Bist du durch die 100 Zeilen durch, und die nächsten Zeilen sind noch nicht da, dann bleibt die Prozedur eben beim FETCH stehen und wartet.

Das geht aber auch nur dann wenn du keine Aggregationen im Statement hast, sprich ein GROUP BY oder eine DISTINCT. Für diese Funktionen braucht Oracle logischerweise erst alle Sätze bevor das Endergebnis feststeht.

In diesem Fall wäre dir vielleicht mit einer Materialized View geholfen um die Abfrage generell zu beschleunigen.
 
OK glaube das mit dem Cursor ist die beste Lösung. Werde es mal versuchen! Besten Dank mal.

Noch kurz was? Wenn ich ne Materialized View (Snapshot) machen würde, bedeutet das doch das ich eine Replication erstelle
 
Richtig, eine MView ist im Grunde eine vorbereitete Abfrage. Wird oft im Data Warehouse Umfeld genutzt um Berichte über Massendaten bereits verdichtet abzulegen.
In Fall von MViews nimmt man etwas Redundanz zu Gunsten der Performance in Kauf.

Das schöne an MViews ist, dass ich den Zeitpunkt der Aktualisierung recht gut bestimmen kann, d.h. ich kann sagen "berechne die MView alle 2 Stunden neu" oder "jedesmal wenn sich an den Basisdaten was ändert".
 
Hallo,

habe das mit dem Cursor implementier und es funktioniert einwandfrei. Die Abfrage dauerte ohne Cursor ca. 1.45 Minuten. Mit Curso sind es jetzt nur noch Millisekunden!

Suuuper Vielen Dank!
 

Neue Beiträge

Zurück