PDA

View Full Version : [gelöst] SETLL und READ mit Gruppenwechsel ???



Seiten : [1] 2

FNeurieser
23-04-12, 12:44
Hallo allerseits,

wieder einmal habe ich ein Problem bei dem ich nicht mehr weiterkomme.

Eine vollprozedurale Datei die 3 Keyfelder mit jeweils 3 numerischen Stellen aufweist soll durchgelesen werden.
Das Problem dabei. Jedes der Keyfelder kann mit Werten von - bis vorbelegt werden, wobei die Werte zwischen 1 und 999 liegen können. Festzuhalten ist, dass lediglich das erste Keyfeld einen Eintrag größer als 0 aufweisen muss.

also z.B.:
Key01: von 50 bis 51
Key02: 0
Key03: 0

ist genauso möglich wie
Key01: von 1 bis 900
Key02: von 1 bis 999
Key03: von 1 bis 999

Ich setze also mit SETLL auf die Datei auf:


KeyLIST SETLL FILE
Do *Hival
READ FILE
IF %EOF(FILE)
LEAVE
ENDIF
.
.
.

EndDo

Wie muss ich vorgehen, damit bei Erreichen der jeweiligen BIS-Werte entsprechend reagiert werden kann?
Wird z.B. bei Key03 der Wert 999 erreicht, so muss erneut mit folgenden Werten aufgesetzt werden:
Key01: von 1 bis 900
Key02: von 2 bis 999
Key03: von 1 bis 999

und wird bei Key02 999 erreicht, so muss erneut aufgesetzt werden:
Key01: von 2 bis 900
Key02: von 1 bis 999
Key03: von 1 bis 999

Wie kann ich das ausprorammieren ohne Gruppenwechselschalter zu verwenden, die ja nur bei Primärdateien möglich sind?

Ich bräuchte wirklich dringend wieder eure Hilfe bei diesem Problem.
Danke schon mal im Voraus.

Pikachu
23-04-12, 13:27
Wenn du eine entsprechende logische Datei mit Zugriffspfad und Selektion anlegst, die nur die zutreffenden Datensätze enthält, und als geschlüsselte Datei ins Programm einbindest, dann brauchst du keinen Gruppenwechsel.

A UNIQUE
A R NUMF PFILE(NUMP)
A NUM1 3S
A NUM2 3S
A NUM3 3S
A K NUM1
A K NUM2
A K NUM3
A S NUM1 COMP(GT 0)
A NUM2 COMP(GT 0)
A NUM3 COMP(GT 0)

FNeurieser
23-04-12, 13:30
Hallo Pikachu,

danke schon mal für den Tip. Das einzige Problem dabei ist, dass ich erst bei Programmaufruf erfahre wie die einzlenen Felder belegt werden. D.h. der Benutzer wählt aus welche Werte die einzelnen Keyfelder beinhalten sollen.

USDAVIS
23-04-12, 13:56
Hallo,

ich nehme an, Du bekommst die Key-Werte als Parameter oder aus einer Benutzer-Eingabe aus einem Format.

Erweitere einfach Dein Template:

KeyLIST SETLL FILE
Do *Hival
READ FILE

IF %EOF(FILE)
LEAVE
ENDIF

IF (Key01 < Key01Min) or
(Key01>Key01Max)
ITER
ENDIF

IF (Key02 < Key02Min) or
(Key02 > Key02Max)
ITER
ENDIF

IF (Key03 < Key03Min) or
(Key03 > Key03Max)
ITER
ENDIF

...
(Verarbeitung)
...
EndDo

DIe Min-/Maxwerte musst Du vorher aus der Benutzereingabe ermitteln.

Die Löung ist zwar nicht schön, würde aber ohne zusätzliche logische Sichten und ohne L-Schalter auskommen.

Persönlich würde ich eher zu embedded SQL neigen.

Gruss
Ulli

FNeurieser
23-04-12, 14:08
Hallo Ulli,



Persönlich würde ich eher zu embedded SQL neigen.


tja embedded SQL wäre sicher ein Möglichkeit und zwar sicher nicht die schlechteste; leider aber stehe ich mit den Pointern und so nicht gerade auf freundschaftlichem Fuß und weiss daher auch nicht wie ich so etwas umsetzen könnte.

Jedenfalls recht herzlichen Dank für die "unsaubere" Lösungsmöglichkeit.

LG
Franz

B.Hauser
23-04-12, 14:30
Embedded SQL arbeitet NICHT (direkt) mit Pointern!

Was Du brauchst ist ein Cursor, der mit dem SQL-Befehl DECLARE CURSOR definiert wird und auf einem SQL-Statement basiert (Äquivalent zu der F-Bestimmung). Die Von- und Bis-Werte können als Host-Variablen (mit führendem Doppel-Punkt) direkt in das SELECT-Statement eingebunden werden.
Der Cursor wird mit dem SQL-Befehl OPEN geöffnet (analog Open bei User controlled open). Anschließend die einzelnen Datensätze mit dem Befehl FETCH empfangen (analog zu READ/READE etc in Datenstrukturen). Die empfangenen Werte können dann verarbeitet werden. Wurden alle Sätze verarbeitet wird der Cursor mit dem SQL-Befehl CLOSE geschlossen.

Etwa so:

/Free
Exec SQL Declare CsrC01 Cursor For
Select Fld1, Fld2, ... FldN
From File
Where Key1 between :VonWert1 and :BisWert1
and Key2 between :VonWert2 and :BisWert2
and Key3 between :VonWert3 and :BisWert3
Order By Key1, Key2, Key3;

Exec SQL Open CsrC01;
DoU 1 = 0;
Exec SQL Fetch Next From CsrC01 into :Var1, :Var2, ... VarN;
If SQLCODE = 100;
Leave;
ElseIf SQLCODE < *Zeros;
//Fehler;
EndIf;
//Verarbeitung
EndDo;
Exec SQL Close CsrC01;

Birgitta

FNeurieser
23-04-12, 14:34
Hallo Brigitta,

danke für die Aufklärungsarbeit. Aber gibt es bei SQL nicht auch Pointer die Verwendung finden. Ich dachte immer wenn ich die Ergebnisse einer SQL-Abfrage in einen Datenbereich einlese werden Pointer verwendet um auf sei zugreifen zu können.

B.Hauser
23-04-12, 14:43
Hallo Brigitta,

danke für die Aufklärungsarbeit. Aber gibt es bei SQL nicht auch Pointer die Verwendung finden. Ich dachte immer wenn ich die Ergebnisse einer SQL-Abfrage in einen Datenbereich einlese werden Pointer verwendet um auf sei zugreifen zu können.

Sofern das SQL Statement zur Laufzeit aufbereitet wird und zur Compile-Zeit weder die Dateien/Tabellen/Views noch die Spalten, die zur Laufzeit verwendet und ausgewählt werden könnten, noch deren Datentypen und Längen bekannt sind, hat man natürlich keine anderen Chance als über Pointer-Handling zu arbeiten ... und das kommt in der normalen Anwendungsentwicklung in maximal 2% aller Fälle vor.

Birgitta

FNeurieser
23-04-12, 18:13
@Brigitta,

danke für die Info, aber geht es nicht schneller wenn mann die via SQL erhaltenen Daten zuerst in einen Datenbereich übergibt und diesen erst dann abarbeitet wenn SQL alle Daten übergeben hat, anstelle jedesmal ein FETCH durchzuführen und den Satz verarbeiten?

Fuerchau
23-04-12, 18:28
Nö.
Wie willst du denn die Daten anders als per Fetch von SQL holen ?