PDA

View Full Version : SQL0811



Seiten : 1 [2]

andreaspr@aon.at
14-09-12, 08:14
Das stimmt so nicht! SELECT ... INTO oder VALUES ... INTO führen im Hintergrund einen DECLARE, OPEN, FETCH und CLOSE aus! Die ODPs bleiben ab dem 2. Mal öffen, sofern sie wiederverwendbar sind.

Das stimmt so auch nicht! :)
Ja ich hab das Gerücht mal irgendwo gelesen oder gehört, aber Tatsache ist, dass der ODP jedes mal gelöscht wird.
Eventuell dass es bei 7.1 so gemacht wird?
Bis 6.1 wird der ODP jedefalls immer neu erstellt!

B.Hauser
14-09-12, 11:57
Das stimmt so auch nicht! :)
Ja ich hab das Gerücht mal irgendwo gelesen oder gehört, aber Tatsache ist, dass der ODP jedes mal gelöscht wird.
Eventuell dass es bei 7.1 so gemacht wird?
Bis 6.1 wird der ODP jedefalls immer neu erstellt!

Ich weiß zwar nicht wo Du die Gerüchte gehört hast, bzw. wieso du glaubst, dass der ODP jedesmal gelöscht wird. Der ODP wird nur nach der 1. Ausführung gelöscht (wie auch bei den Cursorn) und bleibt nach der zweiten Ausführung offen (sofern er wiederverwendbar ist) und wird erst geschlossen, wenn die Activierungsgruppe beendet wird, zumindest wenn die Option CLOSQLCSR = *ENDACTGRP ist.

Hier ein Auszug aus dem Joblog (auf einer Maschine mit V5R4). SELECT ... INTO wird in einer Schleife mehrfach ausgeführt und das Programm sogar zwei Mal aufgerufen:

> call selintox
ODP erstellt.
Blockung für Abfrage.
Offener Datenpfad (ODP) gelöscht.
Eingebettetes SELECT beendet.
DSPLY Der Gesamt-Umsatz in 2004 liegt bei 2780.00 Euro
ODP erstellt.
Blockung für Abfrage.
ODP nicht gelöscht.
Eingebettetes SELECT beendet.
DSPLY Der Gesamt-Umsatz in 2005 liegt bei 15276.21 Euro
ODP wiederverwendet.
ODP nicht gelöscht.
Eingebettetes SELECT beendet.
DSPLY Der Gesamt-Umsatz in 2006 liegt bei 11409.57 Euro
> call selintox
ODP wiederverwendet.
ODP nicht gelöscht.
Eingebettetes SELECT beendet.
DSPLY Der Gesamt-Umsatz in 2004 liegt bei 2780.00 Euro
ODP wiederverwendet.
ODP nicht gelöscht.
Eingebettetes SELECT beendet.

Birgitta

andreaspr@aon.at
14-09-12, 12:20
Ich weiß zwar nicht wo Du die Gerüchte gehört hast, bzw. wieso du glaubst, dass der ODP jedesmal gelöscht wird. Der ODP wird nur nach der 1. Ausführung gelöscht (wie auch bei den Cursorn) und bleibt nach der zweiten Ausführung offen (sofern er wiederverwendbar ist) und wird erst geschlossen, wenn die Activierungsgruppe beendet wird, zumindest wenn die Option CLOSQLCSR = *ENDACTGRP ist.

Das meinte ich mit Gerücht ;)
Ich habe nämlich zuvor auch ein kleines Test-PGM gestartet, wo ich das gleiche Select INTO Statement 4 mal ausgeführt habe und jedes mal wurde der ODP neu erstellt wurde.

Jetzt hab ich grad das gleiche Statement innerhalb einer Schleife 4 mal ausgeführt und plötzlich bleibt der ODP geöffnet.
Außerhalb der Schleife scheint der ODP immer gelöscht zu werden. Warum auch immer!?!? (6.1)

Weist du oder sonst wer eine vernünftige erklärung dafür??

Ich habe (auch bei 5.4) jedenfalls erhebliche verbesserungen der Performance in diversen Programmen tätigen können indem ich einen Cursor verwendete, weil scheinbar nicht immer das Select Into Statement mit dem gleichen ODP verwendet wurde.

Deshalb sag ich auch dass ein Cursor besser sei als ein Select Into, denn du kannst nie zu 100 % sagen, dass da der ODP offen bleibt, bei einem Cursor kann ich das schon. (Abhängig von den SET OPTIONs natürlich).

andreaspr@aon.at
14-09-12, 21:03
Jetzt hab ich grad das gleiche Statement innerhalb einer Schleife 4 mal ausgeführt und plötzlich bleibt der ODP geöffnet.
Außerhalb der Schleife scheint der ODP immer gelöscht zu werden. Warum auch immer!?!? (6.1)

Weist du oder sonst wer eine vernünftige erklärung dafür??

Während der Beiträge im anderen Thrad (Plan Cache und Monitor) denke ich die Antwort zu haben.

Für jedes Select wird ja generell ein eigener Cursor erstellt. So wird auch für ganz genau dem gleichem Select an einer anderen Stelle im Programm ein eigener Cursor erstellt.
Dadurch wird der ODP vom ersten Select nicht für das zweite verwendet auch wenn es 1:1 das gleiche ist.

Das ist der Grund warum der ODP eines SELECT INTOs innerhalb einer Schleife öfters verwendet wird jedoch das gleiche Statement hintereinander nicht.
Da die Statements hintereinander jedes einen eigenen Cursor hat.

Somit konnte ich die Thematik SELECT INTO und ODPs auch nun durchblicken.
Danke Birgitta für den Denkanstoß! :)

Fuerchau
15-09-12, 10:07
Warum sollte man den selben SQL in einem Programm auch mehrfach kodieren?

Jedes SQL-Statement bekommt eine Statement-ID. Der ODP hängt natürlich am Statement. Verwendet man also mehrere Statements mit dem selben Befehl gibts auch mehrere ODP's.

Ruft man also diese mehreren Statements auch mehrfach auf so wird je Statement halt auch ein ODP offen gehalten.

Das obige Testscenario mit mehreren Statements war also einfach unvollständig (nur 1 Mal durchgeführt).

andreaspr@aon.at
15-09-12, 11:14
Warum sollte man den selben SQL in einem Programm auch mehrfach kodieren?

Tja, wenn ich das wüsste. Wie oft mussten wir alle schon mal alte Steinzeitprogramme durchforsten, wo wir uns dachten, warum man das damals so programmierte? ;)

Ansonsten würde ich mal meinen, dass du genau das gleiche geschrieben hast, wie ich zuvor.

B.Hauser
15-09-12, 11:29
Für jedes Select wird ja generell ein eigener Cursor erstellt. So wird auch für ganz genau dem gleichem Select an einer anderen Stelle im Programm ein eigener Cursor erstellt.

Genau das ist ja auch der Grund, warum man (auch) SQL-(SELECT) Statements in Prozeren in Service-Programmen mit benannter Aktivierungsgruppe kapseln sollte. Damit wird die Anzahl der FULL OPENS auf ein Minimum reduziert. Insert-/Update und Delete-Statements sollten ebenfalls gekapselt werden, jedoch in der gleichen Aktivierungsgruppe wie der CALLER laufen. (Stichwort Commitment Control und Transaktionen)

... auch wieder so ein Part, den Kent Milligan und Mike Caine damals aus dem Redbook , an dem ich mitgeschrieben habe mit dem Kommentar rausgestrichten haben: "Basic Knowhow ... must not be included".

Birgitta

BenderD
15-09-12, 12:06
... Kent Milligan, Mike Cain, am Redbook mitgeschrieben...
hat wohl in diesem Fall alles nix geholfen. Datenbankzugriffsmodule sollten normalerweise mit *CALLER erstellt werden, sonst wird das ganze weder Transaktionssicher, noch kann man damit RecordSets verarbeiten.

D*B