PDA

View Full Version : ILE/SQL



Seiten : [1] 2

GS
18-11-03, 16:19
Hallo,
ich lese eine Datei mit ILE/SQL.
Die Datei enthält u.a. ein Datumsfeld mit Datenart L und
DATFMT(*EUR).
Das Datumsfeld enthält den Defaultwert 01.01.0001.
Beim Fetch bekomme ich SQLCOD 183.(Datumsangaben falsch)

Gibt es eine Möglichkeit(ohne jedes Feld,ausgenommen das Datumsfeld, einer Hostvariablen zuzuordnen) diesen Fehler zu umgehen?

Danke für Eure Hilfe
Gruss
G.S.

Fuerchau
18-11-03, 16:26
Ich frage mich da eher, wieso es zu dem falschen Inhalt kommt. Wird denn im interaktiven SQL der gleiche Fehler angezeigt ?

Dann hast du leider keine Chance ausser den Select Feld für Feld aufzubauen.
Alternativ kannst du auch eine LF/View verwenden, die nur die benötigten Felder enthält.

Anmerkung: Ich würde mich da eher um den Datenfehler kümmern als eine Umgehung zu programmieren.

PS: Vielleicht hilft ja auch schon die H-Bestimmung DATFMT(*EUR / *ISO) um eine Formatangleichung durchzuführen.

GS
18-11-03, 16:44
Danke für die Info.

Die Daten werden von einer anderen Software,auf die ich keinen
Einfluss habe,erstellt.
Was mich nur sehr nachdenklich stimmt ist folgende Tatsache:
Wenn Du dieses Feld clearst steht als Defaultwert 01.01.0001
drin. Der Inhalt wird also vom Betriebssystem vergeben,aber dieses Betriebssystem hat anschl.Schwierigkeiten den selbstverbockten M... zu verarbeiten.
Wenn ich normal mit READ lese passiert nichts.
Bein interaktiven SQL steht an dieser Stelle +++++++++++++
die Daten können also da auch nicht verarbeitet werden.

Gruss
G.S.

B.Hauser
18-11-03, 16:56
Hallo GS und Fuerchau,

SQL ist es absolut egal, welches Datums-Format in den D- oder H-Bestimmungen angegeben wurde.

Für SQL zählt folgendes Datums-Format:
1. Interaktives SQL
Das Format, das beim STRSQL im Parameter DATFMT angegeben wurde.
Unterlassungs-Wert ist m.E. *JOB und bei uns ist das Job-Datum z.B. *DMY (also Tag.Monat.2-stelliges Jahr)

2. Embedded SQL
Das Format, das beim CRTSQLRPGI im Parameter DATFMT angegeben wurde.
Auch hier ist der Unterlassungs-Wert *JOB
Um ganz sicher zugehen, dass das richtige Format verwendet wurde, kann man im SQL-Modul das Datums-Format über SET OPTION setzten. SET OPTION überschreibt die Compile-Angaben.
(SET OPTION entspricht den H-Bestimmungen nur halt für SQL!)



C/EXEC SQL
C+ Set Option DatFmt = *EUR
C/END-EXEC


Birgitta

Fuerchau
19-11-03, 09:14
@Birgitta

Wenn ich bei der Umwandlung kein Datumsformat angebe, also *JOB der Unterlassungswert ist, kann ein Datum 01.01.0001 nicht vorkommen, oder sehe ich das falsch ?

Nachricht SQL0183:
Nachricht . . . : Ergebnis eines Datums- oder Zeitmarkenausdrucks ungültig.
Ursache . . . . : Das Ergebnis der Rechenoperation ist ein Datum oder eine
Zeitmarke, das bzw. die sich nicht im gültigen Datumsbereich befindet, der
zwischen 0001-01-01 und 9999-12-31 liegt. Ist das Ergebnis ein Datum im
Format YMD, MDY, DMY oder JUL, muss das Jahr zwischen 1940 und 2039 liegen.
Bei einer Anweisung FETCH oder einer eingebetteten Anweisung SELECT, SET
oder VALUES INTO ist die relative Position der Host-Variablen in der Klausel
INTO &1 und der Name der Host-Variablen ist &2.


Also entweder H-Bestimmung oder "set option ..." !

@GS

Probiers mal beim Fetch mit einer Indicator-Array:

D MyStru DS Extname(...)
D Indic S 5I 0 dim(x)

:
:
EXEC SQL FETCH MyCursor into :MyStru :Indic
END-EXEC

Dies führt auf jeden Fall zum Lesen der Daten.
Im Indic(x) steht -1 bei NULL-Wert, -2 bei Datenfehler !
x ist die Nummer des Feldes in der Struktur.

Das "+++++" beim direkten SQL deutet auf einen fehlerhaften Datums-Wert hin !

BenderD
19-11-03, 09:46
Hallo alle zusammen,

bei Datumsfeldern muss man Speicherung und Verarbeitung auseinander halten:
- gespeichert wird in einem internen Format, in das (zumindest) vom 1.1.0001 bis zum 31.12.9999 jedes theoretisch gültige Datum reinpasst (was immer das genau sein mag, bei zwei mindestens Kalenderreformen bisher)
Die Datenbank stellt sicher, dass kein 32., kein 13. Monat und auch kein 31. April gespeichert wird.
- Bei der Verarbeitung wird dann dieser interne Wert in eine externe Darstellung umgesetzt, wie diese aussieht ist einstellbar. Durch die Art der externen Darstellung kann es nun vorkommen, dass der gesamte Wertebereich, den die Speicherung ermöglicht, nicht komplett darstellbar ist. Wer zum Beispiel das Jahr nur zweistellig haben will, bekommt nur ein Zeitfenster von 100 Jahren hin, sowas macht man halt nicht.

Am einfachsten weicht man all diesen Problemen aus, wenn man darauf achtet immer ein Format zu verwenden, das den gesamten Wertebereich ermöglicht, die Standardformate *EUR oder *ISO sind da einfache und sichere Wahl. Konvertieren kann man dann immer noch.
Bei SQL Programmen wird zur Umwandlungszeit dieses Format festgelegt, entweder mit der Compiletime Anweisung SET OPTION oder beim CRTXXX Befehl, ersteres ist da von Vorteil, da es in der Quelle steht.

mfg

Dieter Bender

B.Hauser
19-11-03, 11:08
Hallo Leute,

Dieter hat das Ganze richtig beschrieben!

Testet doch einfach im interaktiven SQL, in dem ihr das Datums-Format über F13=Service und Auswahl 1=Sitzugsattribute ändern verändert.

Wird eine Datums-Darstellung mit 4-stelligem Jahr angegeben, werden alle Daten zwischen 01.01.0001 und 31.12.9999 angezeigt.
Wird eine Datums-Darstellung mit 2-stelligem Jahr angegeben, werden alle Daten, die ausserhalb des gültigen Bereichs (zwischen 01.01.1940 und 31.12.2039) mit ++++++++ (=Feldüberlauf) dargestellt.
Das heisst jedoch nicht, dass in diesem Feld ein ungültiges Datum hinterlegt ist!

Wichtig ist beim Embedded SQL, dass das SQL-Datums-Format mit dem Datums-Format des Ausgabe-Feldes übereinstimmt.
Das Datums-Format in den Ausgabe-Feldern wird durch die Angaben in den D- und H-Bestimmungen.
(D überschreibt H)
Wurde das Datums-Format weder in den D- noch in den H-Bestimmungen definiert, wird *ISO genommen.

Birgitta

Peet
19-11-03, 12:50
Hallo,

hast Du denn bei der Umwandlung des ILE/SQL auch die Angaben für Date und TIME gemacht ??

Meine ILE/SQL-Programme haben keine Proleme mit
Datums/Zeitfeldern.

Gruss
Peet

rmittag
19-11-03, 12:53
für ganz neugierige. probiert mal das Folgende im interaktiven Sql aus. Dann sieht man, wie das Datumsformat gespeichert wird:


CREATE TABLE QTEMP/TEST (DAS_DATUM DATE NOT NULL WITH DEFAULT)
Tabelle TEST in QTEMP erstellt.
insert into qtemp/test values('2003-11-19')
1 Zeilen in TEST in QTEMP eingefgt.
select * from test
SELECT-Anweisung vollständig verarbeitet.
select hex(das_datum) from test
SELECT-Anweisung vollständig verarbeitet.


Gruss
Rolf

Fuerchau
19-11-03, 13:17
Das sieht man auch mittels DSPPFM und F11 !

Das Problem ist hier ja, dass tatsächlich ein ungültiger Wert in den Daten steckt (Siehe ++++ beim interaktiven Select).

Diese Daten bekomme ich nur gelesen, wenn ich Indicator beim Select verwende (oder das Feld nicht auswähle), ansonsten bekomme ich halt den Fehler und keine Daten !

Eine Indicator-Array beim "fetch into" ist hier die Lösung, wenn ich denn nicht jedes Feld einzeln hinschreiben will.