[NEWSboard IBMi Forum]
  1. #1
    Registriert seit
    Dec 2003
    Beiträge
    23

    Question Verschiedene Datumsformate in RPG

    Hallo zusammen!

    Ich hänge gerade in RPG an einem sehr seltsamen Datumsproblem! Vielleicht (bzw. so wie ich euch kenne "bestimmt") weiß ja jemand ne Lösung:

    In habe in ein RPG-Programm unter anderem 2 Dateien gebunden!

    Datei A:
    Die eine Datei ist als externe Datenstruktur eingebunden und wird per SQL auf einer anderen AS400 gefüllt.

    Ddslbmkk000 E DS extname(lbmkk000)
    Prefix(ak)

    Datei B:
    Die 2. Datei ist eine extern beschriebene Datei auf der lokalen AS400, aus der Daten per READE ausgelesen werden.

    ordrhdr01 uf e K disk Prefix(hd)

    In beiden Dateien ist ein Datumsfeld vom Typ "DATE" vorhanden und ich möchte nun das Feld aus Datei B in Datei A schieben!
    Soweit alles kein Thema! Zumindest eigentlich....

    Ich fülle nun das Feld in der Datenstrukter (akAUFDATHS = hdAUFDATHS und machen den SQL-INSERT auf Datei A!

    Beim SQL fällt das Programm auf die Nase! Meldung: "Die Jahresangabe eines Datums- oder Zeitmarkenwerts liegt nicht innerhalb des korrekten Bereichs"

    Habe dann mal nen Dump gemacht und mir die Felder angesehen:
    Feld aus Datei A: 0001-01-01
    Feld aus Datei B: 01.01.0001

    Im Header habe ich für das Datumsformat noch folgenden Eintrag gemacht: H DATFMT(*EUR)

    Wieso ist das Datumformat in den Dateien unterschiedlich??
    Hat das was mit SQL zu tun und ich muss das Feld erst umstellen?

    Besten Dank schon mal....

    Tobias Heinemann

  2. #2
    Registriert seit
    Aug 2001
    Beiträge
    2.875
    Zitat Zitat von TobiasHe
    Hallo zusammen!

    Ich hänge gerade in RPG an einem sehr seltsamen Datumsproblem! Vielleicht (bzw. so wie ich euch kenne "bestimmt") weiß ja jemand ne Lösung:

    In habe in ein RPG-Programm unter anderem 2 Dateien gebunden!

    Datei A:
    Die eine Datei ist als externe Datenstruktur eingebunden und wird per SQL auf einer anderen AS400 gefüllt.

    Ddslbmkk000 E DS extname(lbmkk000)
    Prefix(ak)

    Datei B:
    Die 2. Datei ist eine extern beschriebene Datei auf der lokalen AS400, aus der Daten per READE ausgelesen werden.

    ordrhdr01 uf e K disk Prefix(hd)

    In beiden Dateien ist ein Datumsfeld vom Typ "DATE" vorhanden und ich möchte nun das Feld aus Datei B in Datei A schieben!
    Soweit alles kein Thema! Zumindest eigentlich....

    Ich fülle nun das Feld in der Datenstrukter (akAUFDATHS = hdAUFDATHS und machen den SQL-INSERT auf Datei A!

    Beim SQL fällt das Programm auf die Nase! Meldung: "Die Jahresangabe eines Datums- oder Zeitmarkenwerts liegt nicht innerhalb des korrekten Bereichs"

    Habe dann mal nen Dump gemacht und mir die Felder angesehen:
    Feld aus Datei A: 0001-01-01
    Feld aus Datei B: 01.01.0001

    Im Header habe ich für das Datumsformat noch folgenden Eintrag gemacht: H DATFMT(*EUR)

    Wieso ist das Datumformat in den Dateien unterschiedlich??
    Hat das was mit SQL zu tun und ich muss das Feld erst umstellen?

    Besten Dank schon mal....

    Tobias Heinemann
    Das Problem ist, dass SQL das Datums-Format, das in den D- oder H-Bestimmungen angegeben ist überhaupt nicht interessiert.
    Das Datums-Format, das SQL verwendet kann wie folgt gesetzt werden:
    1. Im interaktiven SQL über F13 Sitzungs-Attribute ändern
    2. Im iSeries Navigator über Verbindung --> JDBC Setup --> Format
    3. Im Compile-Befehl CRTSQLxxxI Option DATFMT
    4. In Embedded SQL oder SQL/PL über SET OPTION

    Ich nehme an, dass der SQL-Befehl im RPG-Programm als embedded SQL abgesetzt wird.
    In diesem Fall würde ich empfehlen folgendes SQL-statement einzubinden.

    C/EXEC SQL Set Option DatFmt = *ISO
    C/END-EXEC

    Wichtig ist, dass das SQL-Datums-Format ein 4-stelliges Jahr verarbeitet. Welches ist egal.

    Birgitta
    Birgitta Hauser

    Anwendungsmodernisierung, Beratung, Schulungen, Programmierung im Bereich RPG, SQL und Datenbank
    IBM Champion seit 2020 - 4. Jahr in Folge
    Birgitta Hauser - Modernization - Education - Consulting on IBM i

  3. #3
    Registriert seit
    Dec 2003
    Beiträge
    23

    Question

    Recht schönen Dank für die schnelle Hilfe Brigitta!!

    Mein Programm läuft nun auch schon mal durch und führt den SQL-INSERT durch! Ein neues Problem ist dabei allerdings entstanden. Scheinbar habe ich irgendwo noch eine Einstellung falsch....

    Wenn ich mir nämlich die Daten per interaktivem SQL in der neu gefüllten Tabelle anschaue, dann wird mein Datumfeld als fehlerhaft angezeigt! In den Sitzungsattributen ist als Datumformat *DMY eingetragen...
    Schalte ich das Format auf *ISO oder *EUR, wird das Datum auch richtig angezeigt! Gibt es bei *DMY irgendwie ein Probleme mit dem Lowvalue 0001-01-01??

    Das finde ich doch mehr als seltsam.... hat da noch jemand ne Idee!???

    Besten Dank noch mal...
    Tobias

  4. #4
    Registriert seit
    Aug 2001
    Beiträge
    2.875
    Zitat Zitat von TobiasHe
    Recht schönen Dank für die schnelle Hilfe Brigitta!!

    Mein Programm läuft nun auch schon mal durch und führt den SQL-INSERT durch! Ein neues Problem ist dabei allerdings entstanden. Scheinbar habe ich irgendwo noch eine Einstellung falsch....

    Wenn ich mir nämlich die Daten per interaktivem SQL in der neu gefüllten Tabelle anschaue, dann wird mein Datumfeld als fehlerhaft angezeigt! In den Sitzungsattributen ist als Datumformat *DMY eingetragen...
    Schalte ich das Format auf *ISO oder *EUR, wird das Datum auch richtig angezeigt! Gibt es bei *DMY irgendwie ein Probleme mit dem Lowvalue 0001-01-01??

    Das finde ich doch mehr als seltsam.... hat da noch jemand ne Idee!???

    Besten Dank noch mal...
    Tobias
    Hallo Tobias,

    Vielleicht sollte ich mal etwas weiter ausholen:
    Die interne Darstellung eines Datums (also so wie es in einer DB2 UDB-Datei steht) ist 4 byte Binär und stellt einen laufenden Zähler ab Datum x dar.

    Was man an der Oberfläche sieht, bzw. was in RPG über DatFMT gesetzt wird, ist nur die Umsetzung diese Datums in eine leserliche Form. (Deshalb ist es auch möglich zwei Datums-Felder mit unterschiedlichem Format zu vergleichen!)

    Allerdings gibt es Restriktionen für die Darstellung von Datums-Felder mit 2-stelligem Jahr (z.B. *DMY).
    Der gültige Bereich liegt zwischen 01.01.1940 und 31.12.2039.
    Der 01.01.0001 ist also ausserhalb dieses Bereichs.
    Der *LOVAL bei einem Datum mit 2-stelligem Jahr ist nicht 01.01.0001, sondern 01.01.1940.

    Deshalb wird bei der Einstellung *DMY im interaktiven SQL ein ungültiges Datum angezeigt. SQL selber interessiert die Aufbereitung eigentlich nicht, d.h. im interaktiven SQL kannst Du ohne Probleme einen Satz mit Datum 01.01.0001 einfügen.

    Beim embedded SQL sieht das etwas anders aus. Die Restriktionen werden von RPG festgelegt, das Format im SQL-Statement von SQL. Die Unstimmigkeiten sind wohl auf gewisse Konversations-Problemen zwischen Toronto (RPG-Compiler-Entwicklung) und Rochester (Datenbank und SQL) zurückzuführen.

    Birgitta
    Birgitta Hauser

    Anwendungsmodernisierung, Beratung, Schulungen, Programmierung im Bereich RPG, SQL und Datenbank
    IBM Champion seit 2020 - 4. Jahr in Folge
    Birgitta Hauser - Modernization - Education - Consulting on IBM i

  5. #5
    Registriert seit
    Mar 2002
    Beiträge
    5.287
    @Birgitta

    das ist weniger ein Nord-Süd Konflikt, sondern eigentlich nur konsequent:

    SQL ist streng typisiert, alles und jedes wird auf Typverträglichkeit überprüft und der 1.1.01 passt nun mal nicht in eine Feld mit einem Typ, der einen Wertebereich vom 1.1.1940 bis 31.12.2039 hat.

    RPG kennt intern keinerlei Typprüfung, da kann man jeden Murks in jedes Feld reinquengeln, egal ob das dann stimmt, oder nicht, ich sage da nurmal Feldüberlagerung in Datenstruktur.

    mfg

    Dieter Bender

    Zitat Zitat von B.Hauser
    Hallo Tobias,

    Vielleicht sollte ich mal etwas weiter ausholen:
    Die interne Darstellung eines Datums (also so wie es in einer DB2 UDB-Datei steht) ist 4 byte Binär und stellt einen laufenden Zähler ab Datum x dar.

    Was man an der Oberfläche sieht, bzw. was in RPG über DatFMT gesetzt wird, ist nur die Umsetzung diese Datums in eine leserliche Form. (Deshalb ist es auch möglich zwei Datums-Felder mit unterschiedlichem Format zu vergleichen!)

    Allerdings gibt es Restriktionen für die Darstellung von Datums-Felder mit 2-stelligem Jahr (z.B. *DMY).
    Der gültige Bereich liegt zwischen 01.01.1940 und 31.12.2039.
    Der 01.01.0001 ist also ausserhalb dieses Bereichs.
    Der *LOVAL bei einem Datum mit 2-stelligem Jahr ist nicht 01.01.0001, sondern 01.01.1940.

    Deshalb wird bei der Einstellung *DMY im interaktiven SQL ein ungültiges Datum angezeigt. SQL selber interessiert die Aufbereitung eigentlich nicht, d.h. im interaktiven SQL kannst Du ohne Probleme einen Satz mit Datum 01.01.0001 einfügen.

    Beim embedded SQL sieht das etwas anders aus. Die Restriktionen werden von RPG festgelegt, das Format im SQL-Statement von SQL. Die Unstimmigkeiten sind wohl auf gewisse Konversations-Problemen zwischen Toronto (RPG-Compiler-Entwicklung) und Rochester (Datenbank und SQL) zurückzuführen.

    Birgitta
    AS400 Freeware
    http://www.bender-dv.de
    Mit embedded SQL in RPG auf Datenbanken von ADABAS bis XBASE zugreifen
    http://sourceforge.net/projects/appserver4rpg/

  6. #6
    Registriert seit
    Aug 2001
    Beiträge
    2.875
    Zitat Zitat von BenderD
    @Birgitta

    SQL ist streng typisiert, alles und jedes wird auf Typverträglichkeit überprüft und der 1.1.01 passt nun mal nicht in eine Feld mit einem Typ, der einen Wertebereich vom 1.1.1940 bis 31.12.2039 hat.

    Dieter Bender
    @ Dieter,

    dann erkläre mir doch mal bitte, warum in folgendem Programm ein Satz ordnungsgemäss in eine Datei geschrieben und angezeigt wird, obwohl das verwendete SQL-Format nur ein 2-stelliges Jahr zulässt.

    PHP-Code:
    D MyRPGDate       S               D   DatFmt(*ISO)        
    C/EXEC SQL Set Option DatFmt = *DMYCommit = *None                  
    c
    /END-EXEC                                                           
                                                                         
    C
    /EXEC SQL                                                           
    C
    Create Table QTEMP/MyDateTable                                    
    C
    +        (MyDate Date Not NULL with Default)                        
    C/END-EXEC                                                           
                                                                         
    C
    /EXEC SQL Insert into QTEMP/MyDateTable Values(Date('0001-01-01'))  
    c/END-EXEC                                                           
                                                                         
    C
    /EXEC SQL Select Min(MyDateinto :MyRPGDate from MyDateTable       
    C
    /END-EXEC                                                    
    C     MyRPGDate     Dsply                                   
    C                   
    Eval      *InLR       = *On 
    Und jetzt erkläre mir, warum im folgenden Beispiel ein Satz in die Datei geschrieben wird, aber beim SELECT INTO ein Abbruch erfolgt mit RNQ0114 - Die Jahresangabe eines Datums- oder Zeitmarkenwerts liegt nicht innerhalb des korrekten Bereichs (C G D F).
    (Der einzige Unterschied ist, dass ich die Datums-Formate von SQL und RPG vertauscht habe)

    PHP-Code:
    D MyRPGDate       S               D   DatFmt(*DMY
    C/EXEC SQL Set Option DatFmt = *ISOCommit = *None                   
    c
    /END-EXEC                                                            
                                                                          
    C
    /EXEC SQL                                                            
    C
    Create Table QTEMP/MyDateTable                                     
    C
    +        (MyDate Date Not NULL with Default)                         
    C/END-EXEC                                                            
                                                                          
    C
    /EXEC SQL Insert into QTEMP/MyDateTable Values(Date('0001-01-01'))   
    c/END-EXEC                                                            
                                                                          
    C
    /EXEC SQL Select Min(MyDateinto :MyRPGDate from MyDateTable        
    C
    /END-EXEC                                                     
    C     MyRPGDate     Dsply                                     
    C                   
    Eval      *InLR       = *On 
    Birgitta
    Birgitta Hauser

    Anwendungsmodernisierung, Beratung, Schulungen, Programmierung im Bereich RPG, SQL und Datenbank
    IBM Champion seit 2020 - 4. Jahr in Folge
    Birgitta Hauser - Modernization - Education - Consulting on IBM i

  7. #7
    Registriert seit
    Feb 2001
    Beiträge
    20.247
    Der Unterschied liegt darin, dass beim Insert eine Konstante verwendet wird und diese ist korrekt, da das Datum der DB ja alles aufnehmen kann.
    Probleme gibt es aber beim KONVERTIEREN DB <=> Programm !!!
    Dienstleistungen? Die gibt es hier: http://www.fuerchau.de
    Das Excel-AddIn: https://www.ftsolutions.de/index.php/downloads
    BI? Da war doch noch was: http://www.ftsolutions.de

  8. #8
    Registriert seit
    Dec 2003
    Beiträge
    23

    Thumbs up

    A ja... sowas habe ich gerade auch noch mal in der RPG-Hilfe gefunden! Macht sinn, dass er dann nen Fehler zeigt!

    Aber gut... schönen Dank noch mal für die Hilfe!!

    Viele Grüße,
    Tobias

  9. #9
    Registriert seit
    Aug 2001
    Beiträge
    2.875
    Zitat Zitat von Fuerchau
    Der Unterschied liegt darin, dass beim Insert eine Konstante verwendet wird und diese ist korrekt, da das Datum der DB ja alles aufnehmen kann.
    Probleme gibt es aber beim KONVERTIEREN DB <=> Programm !!!
    Ok, es gibt einen Abbruch, wenn man eine Host-Variable mit anderem Format verwendet, aber die Fehlermeldung ist RNX0114, also eindeutig ein RPG-Fehler! Ein SQL-Fehler würde einen negativen SQLCOD zurückbringen!

    Birgitta
    Birgitta Hauser

    Anwendungsmodernisierung, Beratung, Schulungen, Programmierung im Bereich RPG, SQL und Datenbank
    IBM Champion seit 2020 - 4. Jahr in Folge
    Birgitta Hauser - Modernization - Education - Consulting on IBM i

  10. #10
    Registriert seit
    Mar 2002
    Beiträge
    5.287
    @Birgitta

    1. Die Felder in der Datenbank haben ein internes Format, das beim Übergang zu Hostvariablen konvertiert wird.

    2. Die SQL Anweisung SET OPTION (oder CRTSQLXXX äquivalent) ist eine Compiletime Anweisung für embedded SQL, bei interaktivem SQL und wirkt auf die Konvertierung zwischen alfa und internem Datumsformat und hat Auswirkungen auf Gültigkeitsbereiche (sliding Window für 2 stellige Jahresangaben).

    3. RPG Variablen haben ein Datumsformat, das das Regelwerk steuert wie aus SQL auf (in Wirklichkeit Alfa) Datumsfelder gemappt wird.

    4. Literale haben keine Typbindung und RPG versucht das irgendwie hinzukriegen. Für Eingabewerte sind die immer interpretierbaren Formate (Trennzeichen, Reihenfolge, Länge) *ISO *EURO *AMI und *JIS immer gültig.


    Zitat Zitat von B.Hauser
    @ Dieter,

    dann erkläre mir doch mal bitte, warum in folgendem Programm ein Satz ordnungsgemäss in eine Datei geschrieben und angezeigt wird, obwohl das verwendete SQL-Format nur ein 2-stelliges Jahr zulässt.

    PHP-Code:
    D MyRPGDate       S               D   DatFmt(*ISO)        
    C/EXEC SQL Set Option DatFmt = *DMYCommit = *None                  
    c
    /END-EXEC                                                           
                                                                         
    C
    /EXEC SQL                                                           
    C
    Create Table QTEMP/MyDateTable                                    
    C
    +        (MyDate Date Not NULL with Default)                        
    C/END-EXEC                                                           
                                                                         
    C
    /EXEC SQL Insert into QTEMP/MyDateTable Values(Date('0001-01-01'))  
    c/END-EXEC                                                           
                                                                         
    C
    /EXEC SQL Select Min(MyDateinto :MyRPGDate from MyDateTable       
    C
    /END-EXEC                                                    
    C     MyRPGDate     Dsply                                   
    C                   
    Eval      *InLR       = *On 
    Birgitta
    Der Insert klappt, da *ISO Literale immer interpretierbar sind (siehe SQL Reference beim set option), Das auslesen klappt, da das interne Format auf das (passende) Format der Host Variablen gemapt wird.

    Zitat Zitat von B.Hauser
    Und jetzt erkläre mir, warum im folgenden Beispiel ein Satz in die Datei geschrieben wird, aber beim SELECT INTO ein Abbruch erfolgt mit RNQ0114 - Die Jahresangabe eines Datums- oder Zeitmarkenwerts liegt nicht innerhalb des korrekten Bereichs (C G D F).
    (Der einzige Unterschied ist, dass ich die Datums-Formate von SQL und RPG vertauscht habe)

    PHP-Code:
    D MyRPGDate       S               D   DatFmt(*DMY
    C/EXEC SQL Set Option DatFmt = *ISOCommit = *None                   
    c
    /END-EXEC                                                            
                                                                          
    C
    /EXEC SQL                                                            
    C
    Create Table QTEMP/MyDateTable                                     
    C
    +        (MyDate Date Not NULL with Default)                         
    C/END-EXEC                                                            
                                                                          
    C
    /EXEC SQL Insert into QTEMP/MyDateTable Values(Date('0001-01-01'))   
    c/END-EXEC                                                            
                                                                          
    C
    /EXEC SQL Select Min(MyDateinto :MyRPGDate from MyDateTable        
    C
    /END-EXEC                                                     
    C     MyRPGDate     Dsply                                     
    C                   
    Eval      *InLR       = *On 
    Birgitta
    Der Insert klappt wieder, weil *ISO Literal, die Konvertierung des internen SQL Formats in die Hostvariable scheitert am zu kleinen Wertebereich der *DMY RPG Variable.

    Anmerkung: der SET OPTION Befehl ist in den beiden Beispielen dermatologisch geprüft (den kann man sich bedenkenlos in die Haare schmieren)

    mfg

    Dieter
    AS400 Freeware
    http://www.bender-dv.de
    Mit embedded SQL in RPG auf Datenbanken von ADABAS bis XBASE zugreifen
    http://sourceforge.net/projects/appserver4rpg/

  11. #11
    Registriert seit
    Mar 2002
    Beiträge
    5.287
    @Birgitta,

    das ist doch gerade der Witz an einer strengen Typprüfung - es wird frühestmöglich geprüft: alles was beim Compile geht, wird dort vernagelt und möglichst wenig zur Runtime.
    Einen SQL Runtime Fehler kannst Du bei dieser Angelegenheit nur mit dynamic SQL hinkriegen.

    Dieter

    Zitat Zitat von B.Hauser
    Ok, es gibt einen Abbruch, wenn man eine Host-Variable mit anderem Format verwendet, aber die Fehlermeldung ist RNX0114, also eindeutig ein RPG-Fehler! Ein SQL-Fehler würde einen negativen SQLCOD zurückbringen!

    Birgitta
    AS400 Freeware
    http://www.bender-dv.de
    Mit embedded SQL in RPG auf Datenbanken von ADABAS bis XBASE zugreifen
    http://sourceforge.net/projects/appserver4rpg/

  12. #12
    Registriert seit
    Feb 2001
    Beiträge
    20.247
    Ausserdem sieh dir die RPG-Umwandlungs-Liste an !
    Die SQL's arbeiten NIE mit den angegebenen RPG-Feldern sondern es werden neue RPG-Felder generiert, die natürlich passen, und dann per RPG-Move übertragen (konvertiert). Daher eben ein RPG-Fehler und kein SQL-Fehler.
    Dienstleistungen? Die gibt es hier: http://www.fuerchau.de
    Das Excel-AddIn: https://www.ftsolutions.de/index.php/downloads
    BI? Da war doch noch was: http://www.ftsolutions.de

Similar Threads

  1. RPG: Client Infos lesen?
    By robertki in forum NEWSboard Programmierung
    Antworten: 25
    Letzter Beitrag: 19-01-07, 08:42
  2. Bibliotheksliste in RPG IV abfragen
    By timeless in forum IBM i Hauptforum
    Antworten: 5
    Letzter Beitrag: 11-01-07, 12:04
  3. Problem mit Java-Methoden Aufruf aus ILE RPG?
    By Stoeberl in forum NEWSboard Programmierung
    Antworten: 8
    Letzter Beitrag: 10-01-07, 10:58
  4. RPG goes Web
    By jth in forum NEWSboard Programmierung
    Antworten: 1
    Letzter Beitrag: 21-12-06, 11:13

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • You may not post attachments
  • You may not edit your posts
  •