PDA

View Full Version : SQLRPG Nullindikator



harkne
22-10-12, 17:48
Hallo zusammen,

Ich habe eine Datei mit Datumsfelder in denen NULL-Werte zulässig sind.

Ich habe im RPG ein SQL ausgeführt und habe mich zunächst gewundert dass ich keine Daten bekommen habe. Bis ich gelesen habe dass ich ein Array brauche welches die Null-Werte empfängt

Ich habe jetzt also folgende D-Bestimmungen



DName+++++++++++ETDsVon++++Bi/L+++IDG.Schl}sselw¦rter+++++
d W@CDICTLP E DS EXTNAME(CDICTLP) INZ
**
d Ary@NulInd s 5i 0 dim(256)


Meine SQL-Routine sieht wie folgt aus:



0806.51 **
0806.52 c/exec sql
0806.53 c+ PREPARE S1 FROM :w@SqlString
0806.54 c/end-exec
0806.55 **
0806.56 c/exec sql
0806.57 c+ DECLARE C1 CURSOR FOR S1
0806.58 c/end-exec
0806.59 **
0806.60 c/exec sql
0806.61 c+ OPEN C1
0806.62 c/end-exec
0806.63 **
0806.65 **
0806.66 c/exec sql
0806.67 c+ WHENEVER NOT FOUND GOTO Sb32SqlDlcE
0806.68 c/end-exec
0806.70 c/exec sql
0806.71 c+ FETCH NEXT FROM C1 INTO :W@CDICTLP :Ary@NulInd
0806.72 c/end-exec


Jetzt hab ich gelesen wenn ich z.B. mein Datumsfeld (13. Feld in der Datei) auf NULL abfragen möchte muss ich auf das 13. Element im Array Ary@NulInd abfragen.
Das würde ja auch bedeuten wenn sich die Datei ändert und man ein Feld vor dem Datumsfeld einfügt dass man daran denken muss und die Array-Elemente anpassen muss.

Jetzt meine Frage.

Kann man dies auch irgendwie eleganter lösen, oder bleibt mir dann nur übrig auf den tatsächlichen Wert im Feld z.B. '01-01-0001' zu prüfen ?

Vielen Dank für die Hilfe

Viele Grüße Harald

ExAzubi
23-10-12, 06:48
Hallo,

wichtiger Unterschied

'01-01-0001' ist kein NULL-Wert sondern quasi das *LOVAL des Datumwertes. Daher wird dir eine Abfrage auf NULL nichts bringen, sondern nur auf *LOVAL.

In der DB2 werden bei Datumsfelder (leg keine hand in Feuer ;)) NULL Werte auf den *LOVAL Wert gesetzt.

Was du aber bei allen Feldern machen kannst, ist eine Abfrage auf
%NULLIND

IF %NULLIND(FELDNAME)
....
ENDIF

Daher brauchst du keine Reihenfolge zu wissen und du kannst das richtige Feld immer sauebr verarbeiten

andreaspr@aon.at
23-10-12, 09:37
Hallo,
%NULLIND(FELDNAME) funktioniert nur mit Native I/O und der H-Spec

H ALWNULL(*USRCTL)

In der DB2 gibt es auch für Datumsfelder NULL-Values.
Liest du mit Fetch den nächsten Satz ein und enthält diese Spalte einen NULL-Value, dann wird die Datums-Variable NICHT verändert, sondern eben nur ein Kennzeichen im Indikator-Feld gesetzt.
Das '01-01-0001' was du erhälst, stand sicher auch schon vor dem Fetch drinnen.
Wichtig ist nur, vor jedem Fetch auch ein CLEAR der Datenstruktur gemacht wird. Sonst passiert es, dass du den Wert des vorherigen Satzes prüfst.
Wenn du nicht vorher den Indikator prüfst.

lg Andreas

B.Hauser
23-10-12, 14:50
Jetzt hab ich gelesen wenn ich z.B. mein Datumsfeld (13. Feld in der Datei) auf NULL abfragen möchte muss ich auf das 13. Element im Array Ary@NulInd abfragen.
Das würde ja auch bedeuten wenn sich die Datei ändert und man ein Feld vor dem Datumsfeld einfügt dass man daran denken muss und die Array-Elemente anpassen muss.


... und wieder ein Grund warum man es unbedingt vermeiden sollte alle Felder mit SELECT * auszuwählen, sondern explizit nur die, die auch tatsächlich gebraucht werden!

... bei einer Datei-Änderung müsstest Du bei der Verwendung von SELECT * und Ausgabe in eine externe Datenstruktur zumindest Dein Programm umwandeln.

... bei einer expliziten Auswahl hätte man die Chance einen NULL-Wert mit der Skalaren Funktion COALESCE in einen Default-Wert umzuwandeln.

... und bei einer Datei-Änderung würde nichts passieren.

Birgitta

harkne
25-10-12, 15:51
Vielen Dank für die Antworten.

Fuerchau
25-10-12, 18:49
Bei Select * ist keine Programmumwandlung erforderlich, da der Compiler die aktuellen Struktur feststellt und einen entsprechenden SQL generiert.
Eine nachträgliche Änderung des Programmes weil sich die Datei ändert ist nicht erforderlich.

Aber es ist immer besser (aber eben Tiparbeit) jedes Feld zu benennen.
Somit kann man beim Fetch gezielt für jedes Feld den NULL-Indikator definieren:

fetch MyCursor into
: F1 : NullF1
, : F2 : NullF2
, ...

Man beachte, dass der NullIndikator ohne Komma auf das Feld folgt.
Felder, die nie NULL enthalten können bedürfen auch kein Null-Indikator.