Anmelden

View Full Version : embedded SQL - close cursor



Seiten : 1 [2] 3

BenderD
30-09-05, 11:41
Hallo,

hier muss man Cursor und ODP auseinanderhalten.
Im Programm habe ich einen Cursor, dessen öffnen zur neu Psoitionierung führt und desse Status nur zwichenn open und close wechseln kann; alles andere verursacht Fehler.
Die Datenbank kennt einen ODP, den sie besser offen lässt, da er meist nochmal gebraucht wird und der dann Sperren auf die Tables hat.
Das ganze CLOSQLCSR Gedönse wirkt auf Cursor und nicht auf ODPs, auch wenn es zuweilen anders ausschauen mag!
ODPs, die keiner benutzt, werden von SQL automatisch geräumt, wenn sie von SQL benötigt werden. Dasselbe erreicht man auch mit ALCOBJ CONFLICT(*RQSRLS) wenn einen das irgendwann mal stört.

@Birgitta:
Mit dem neu eröffnen von ODPS in laufenden Programmen habe ich unter V5R3 schon positive Überraschungen erlebt (nach anlegen eines Index)
Wenn Daten komplett über einen Zugriffspfad geholt werden können, dann ist meist mit dem Design was faul, ausser bei Where in Subselect Konstrukten, wo select * eh' nicht geht.

mfg

Dieter Bender

Armin
04-10-05, 06:43
Dass der Cursor offen bleibt, hat intern was mit Optimierungen zu tun.
Du kannst deine SQL's beschleunigen wenn du statische SQL's verwendest:

declare Filecursor cursor for
select * from FILE where ALPHAFELD=:MYFIELD

MYFIELD wird einfach als RPG-Feld definiert.
Damit sparst du dir den Prepare.
Deinen Vorschlag auf statisches SQL zurückzugreifen hab ich versucht:
declare Filecursor cursor for Filesection
open Filecursor
SQLCOD = -514 (kein prepaire durchgeführt) !?

Andere Frage noch:
In der SELECT-Anweisung wurden 2 Tabellen mit LEFT JOIN verbunden.
Jedes Dateifeld einzeln anzusprechen find ich bei großem Umfang nervig. Deshalt "*" und INTO in die externe DS, die ich mit der DDS beschrieben habe. Was aber wenn ich nun 2 Tabellen anspreche?

JonnyRico
04-10-05, 07:20
Hi Armin,

das was du da gemacht hast ist ja eher dynamisch als statisch.

Dynamisch:


SQLStat = 'Select Kunde From Kundenstamm Where Nummer = ' + VarKDNR

Prepare DynSQL From SQLStat

Declare MyCur for DynSQL

Open MyCur



Statisch:



Declare MyCur for
Select Kunde From Kundenstamm Where Nummer = :VarKDNR

Open MyCur


Gruß

Sascha

B.Hauser
04-10-05, 07:22
Andere Frage noch:
In der SELECT-Anweisung wurden 2 Tabellen mit LEFT JOIN verbunden.
Jedes Dateifeld einzeln anzusprechen find ich bei großem Umfang nervig. Deshalt "*" und INTO in die externe DS, die ich mit der DDS beschrieben habe. Was aber wenn ich nun 2 Tabellen anspreche?

Dann definierst Du halt für jede Datei eine Datenstruktur und gibst sie beide beim Fetch an. Für die zweite Datei solltest Du außerdem eine Datenstruktur mit Indikator-Variablen verwenden, um festzustellen, ob NULL-Werte übertragen wurden.


C/EXEC SQL Fetch CsrC1 into :DSFile1, :DSFile2 :DSIndFile2
C/END-EXEC


Auch wenn es dir "nervig" erscheint Felder auszuwählen, SELECT * ist Gift für die Performance. Werden nur einzelne Felder ausgewählt können in einem Block wesentlich mehr Informationen eingelesen werden.

Birgitta

Armin
04-10-05, 07:37
Danke Sascha,
nachdem ich noch CURSOR eingefügt habe, wandelt der Precompile um.
Declare MyCur CURSOR for DynSQL
Jetzt bekomm ich aber den SQLCOD -501. Cursor wurde nicht geöffnet!?

Armin
04-10-05, 07:40
Danke Hr. Hauser für die Info.
Hat auch soweit geklappt. Nur die 3. DS übersteigt mein Verständnis.
Wie muss diese def. werden? Sollte es in der 2. Tabelle keinen passenden Satz geben würde die 2. DS nicht mit Blanks bzw. Nullen init.?

JonnyRico
04-10-05, 07:47
Hi,

also das könnte vielleicht daran liegen das ich mir bei dem o.a. Statement die Hochkommas geschenkt habe. Du müsstest bei der Variable die abfegragt wird noch '''' (für ein Hochkomma) vor und hinter der Variable einfügen.

Zu der von Birgitta (übrigens Fr. Hauser) angesprochenen Sache. Dort handelt es sich um eine Anzeigervariable.

d AnzVar 5I 0

Du also machst:

Fetch CsrC1 into :DSFile1, :DSFile2 :AnzVar

so erhälst du in dem Feld AnzVar den Wert 0, wenn alles okay ist , -1 wenn die Abfrage NULL zurück gibt und -2 wenn dein Feld für den abgefragten Wert zu klein ist.

Gruß

Sascha

Armin
04-10-05, 08:06
Also das funktioniert einfach nicht! Weiterhin SQLCOD -501
FILEselect = 'select * ' +
'from FILE1 left join FILE2 on ' +
'BBELE = STBELE and BPOSI = STPOSI and ' +
'STSTAT = 4 ' +
'where BTEIL<>''E'' and ' +
'BKENN = '':WsGeb'' and BLIEW <= '':WsWoche'' ' +
'order by BKUND, BLIEW' ;
declare FILEcursor CURSOR for FILEselect
open FILECursor
FETCH NEXT FROM AUFGEScursor INTO :FILE1ds, :FILE2ds

Zur Anzeigervariablen:
Entspricht -1 dem SQLCOD 100?
Der Wert -2 entsteht wenn die 2. DS zu wenig Felder hätte?

JonnyRico
04-10-05, 08:41
Nein, weil was du machst ist auch ein Mischmasch aus Dynamisch und Statisch.
Versuch es doch einfach mal mit:



declare FILEcursor CURSOR for
select * from FILE1 left join
FILE2 on BBELE = STBELE and BPOSI = STPOSI and STSTAT = 4
where BTEIL<>'E' and BKENN = :WsGeb and BLIEW <= :WsWoche
order by BKUND, BLIEW

open FILECursor
FETCH NEXT FROM AUFGEScursor INTO :FILE1ds, :FILE2ds

Armin
04-10-05, 09:27
Danke für deine Geduld, aber auch so klappt´s nicht.

C/EXEC SQL
C+ declare AUFGEScursor CURSOR for
C+ select * from AUFGES left join
C+ FESTCKS1 on BBELE = STBELE and BPOSI = STPOSI and STSTAT = 4
C+ where BTEIL<>'E' and BKENN = :WsGeb and BLIEW <= :WsWoche
C+ order by BKUND, BLIEW
C/END-EXEC

C/EXEC SQL
C+ OPEN AUFGEScursor
C/END-EXEC

C/EXEC SQL
C+ FETCH NEXT FROM AUFGEScursor INTO :AUFGESsql, :FESTCKS1sql, :AnzeigerSQL
C/END-EXEC

SQLCOD ist jetzt -305 und AnzeigerSQL = 0
Nachricht . . . : Anzeigervariable erforderlich.
Ursache . . . . : Eine Anweisung FETCH, eine eingebettete Anweisung SELECT,
eine Anweisung CALL, SET oder VALUES INTO hatte einen Nullwert zur Folge,
für Host-Variable &2 wurde jedoch keine Anzeigervariable angegeben. Die
relative Position der Host-Variablen in der Klausel INTO oder der
Parameterliste ist &1. Ist der Name der Host-Variablen *N, wurde ein
SQL-Deskriptorbereich (SQLDA) angegeben.
Fehlerbeseitigung: Eine Anzeigervariable angeben und das Programm erneut
vorumwandeln.

Nach der Compilerliste schein er aber die Variablen in der Select-Anweisung zu nehmen.