[NEWSboard IBMi Forum]

Thema: UDF V6R1

Hybrid View

  1. #1
    Registriert seit
    Aug 2001
    Beiträge
    2.928
    Versuch mal bei dem CASE die SELECT-Anweisung in eine Klapper zu packen.

    Birgitta
    Birgitta Hauser

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

  2. #2
    Registriert seit
    Aug 2006
    Beiträge
    2.114

    UDF stehe auf dem Schlauch

    Hallo *all,

    mir fehlt jetzt nur noch die Konvertierung von hex nach decimal. Finde es auf Anhieb nicht wie der cast aussehen muß. Weil ohne fällt das Teil ab 000A auf die Nase.

    Wie kann man eigentlich solche UDFs debuggen?

    Ansonsten sieht meine UDF so aus.

    Code:
    CREATE FUNCTION rptrade/zaehler /*11.10.19 10:51*/      
    ( DEBITOR dec(08) ) RETURNS                            
    CHAR(04)                                                
    LANGUAGE SQL MODIFIES SQL DATA ALLOW DEBUG MODE         
    DISALLOW PARALLEL                                       
    BEGIN                                                   
    DECLARE RETURNVAL CHAR   (04) NOT NULL DEFAULT '0000' ; 
    DECLARE i_zaehler decimal(04) DEFAULT 0;                
                                                           
     select d020werta into i_zaehler                       
            from dat020 where d020key = debitor;           
     if i_zaehler = 0 then                                 
        select d020werta into i_zaehler                    
               from dat020 order by d020werta desc         
                         fetch first row only;             
        set i_zaehler = i_zaehler + 1;                     
        insert into dat020 (d020key, d020werta)                     
               values(debitor, substr(hex(int(i_zaehler)), 5, 4));  
     end if;                                                        
     set returnval = substr(hex(int(i_zaehler)), 5, 4);             
     RETURN LTRIM(RETURNVAL);                                       
    END
    Last edited by KingofKning; 11-10-19 at 10:25. Grund: Noch Fragen offen

  3. #3
    Registriert seit
    Feb 2001
    Beiträge
    20.696
    Wie wäre es mit

    select 'J' into :vorhanden from datei where exists (...)
    Schließlich enthält der Exists implizit den Fetch first und ist für den Einzelsatzzugriff optimiert.
    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

  4. #4
    Registriert seit
    Mar 2002
    Beiträge
    5.365
    Zitat Zitat von KingofKning Beitrag anzeigen
    Hallo *all,

    mir fehlt jetzt nur noch die Konvertierung von hex nach decimal. Finde es auf Anhieb nicht wie der cast aussehen muß. Weil ohne fällt das Teil ab 000A auf die Nase.

    Wie kann man eigentlich solche UDFs debuggen?

    Ansonsten sieht meine UDF so aus.

    Code:
    CREATE FUNCTION rptrade/zaehler /*11.10.19 10:51*/      
    ( DEBITOR dec(08) ) RETURNS                            
    CHAR(04)                                                
    LANGUAGE SQL MODIFIES SQL DATA ALLOW DEBUG MODE         
    DISALLOW PARALLEL                                       
    BEGIN                                                   
    DECLARE RETURNVAL CHAR   (04) NOT NULL DEFAULT '0000' ; 
    DECLARE i_zaehler decimal(04) DEFAULT 0;                
                                                           
     select d020werta into i_zaehler                       
            from dat020 where d020key = debitor;           
     if i_zaehler = 0 then                                 
        select d020werta into i_zaehler                    
               from dat020 order by d020werta desc         
                         fetch first row only;             
        set i_zaehler = i_zaehler + 1;                     
        insert into dat020 (d020key, d020werta)                     
               values(debitor, substr(hex(int(i_zaehler)), 5, 4));  
     end if;                                                        
     set returnval = substr(hex(int(i_zaehler)), 5, 4);             
     RETURN LTRIM(RETURNVAL);                                       
    END
    wenn ich das richtig verstehe, dann schreibst du einen Satz mit '0001' in dem Huddelfeld in die Datei, wenn ein Satz mit einer 0 (mit oder ohne Hierarchie) schon drinsteht.
    Im Returnwert gibst Du dann '0001' zurück.
    In allen anderen Fällen (kein Satz gefunden, oder schon zwei drin, geht Deine Procedure in die Grütze.

    Ist das so gewollt?

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

  5. #5
    Registriert seit
    Aug 2006
    Beiträge
    2.114
    Zitat Zitat von BenderD Beitrag anzeigen
    wenn ich das richtig verstehe, dann schreibst du einen Satz mit '0001' in dem Huddelfeld in die Datei, wenn ein Satz mit einer 0 (mit oder ohne Hierarchie) schon drinsteht.
    Im Returnwert gibst Du dann '0001' zurück.
    In allen anderen Fällen (kein Satz gefunden, oder schon zwei drin, geht Deine Procedure in die Grütze.

    Ist das so gewollt?

    D*B
    Kann ich jetzt nicht so bestätigen

    Code:
     Anfang auf Zeile . . .
     ....+....1....+....2..
        D020KEY   D020WERTA
              1     0001   
              2     0002   
              3     0003   
              4     0004   
              5     0005   
              6     0006   
              7     0007   
              8     0008   
              9     0009   
             10     000A   
     ********   Datenende
    Vermutlich werde ich mir morgen eine HEX nach DEC Funktion selber schreiben. Habe ich das letzte mal im Informatikunterricht 1982 auf einem CBM 8032 gemacht.
    Hätte nicht gedacht das ich das ein paar Tage später mal für ne AS/400 machen muß die die Funktion nicht kennt.

    GG 4250

  6. #6
    Registriert seit
    Feb 2001
    Beiträge
    20.696
    Ich frage mich nun allen Ernstes, wozu du denn mit HEX=>Dec oder auch zurück nun arbeiten must.

    Das SQL nun mal keine Strukturen kennt und schon gar nicht mit Überlagerungen kannst du in RPGLE durch Overlays von Char mit Int(3), Int(5), int(10) und int(20) Binär nach Dezimal und umgedreht erstellen. Die Hex-Wandlung in SQL ist dann nicht erforderlich.
    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

  7. #7
    Registriert seit
    Aug 2006
    Beiträge
    2.114
    Die Antwort ist simpel: Wir haben leider SAP im Einsatz, und da sind die Kundennummern 8stellig. Weiterhin haben wir unsere Software RP-Trade, und da sind die Kundennummern 5stellig (Preislisten).

    Fällt Dir was auf ;-)
    Richtig, das passt so nicht. Deswegen die Krücke HEX.
    RPG habe ich als COBOL Programmierer nie gemocht und kann es auch nicht. Und da die Aufgabe ja mit SQL lösbar ist, warum nicht. Wobei es mich schon wundert warum man eine HEX-Funktion implementiert aber nicht das Gegenteil davon.

    Aber noch ein paar Stunden, und die Aufgabe ist gelöst. Und wenn ich gemein bin, gebe ich das am Montag meinem Azubi......

    Wobei mir jetzt beim Schreiben eingefallen ist das ich eigentlich ja nur eine fortlaufende Zahl benötige und noch nicht mal hex brauche. (Hex habe ich damals im COBOL Programm gemacht als die Kundenummer noch sechsstellig war und ich auf 5 Stellen mußte)
    Man sieht, drüber diskutieren bringt häufig was.

    GG 4250

  8. #8
    Registriert seit
    Feb 2001
    Beiträge
    20.696
    Aber 8-stellige Kunden geben doch 16-Hexstellen?
    Mach doch einfach eine Mappingtabellen von 8 auf 5-Stellig, das funktioniert ebenso in beide Richtungen.
    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

  9. #9
    Registriert seit
    Mar 2002
    Beiträge
    5.365
    Zitat Zitat von KingofKning Beitrag anzeigen
    Die Antwort ist simpel: Wir haben leider SAP im Einsatz, und da sind die Kundennummern 8stellig. Weiterhin haben wir unsere Software RP-Trade, und da sind die Kundennummern 5stellig (Preislisten).

    Fällt Dir was auf ;-)
    Richtig, das passt so nicht. Deswegen die Krücke HEX.
    RPG habe ich als COBOL Programmierer nie gemocht und kann es auch nicht. Und da die Aufgabe ja mit SQL lösbar ist, warum nicht. Wobei es mich schon wundert warum man eine HEX-Funktion implementiert aber nicht das Gegenteil davon.

    Aber noch ein paar Stunden, und die Aufgabe ist gelöst. Und wenn ich gemein bin, gebe ich das am Montag meinem Azubi......

    Wobei mir jetzt beim Schreiben eingefallen ist das ich eigentlich ja nur eine fortlaufende Zahl benötige und noch nicht mal hex brauche. (Hex habe ich damals im COBOL Programm gemacht als die Kundenummer noch sechsstellig war und ich auf 5 Stellen mußte)
    Man sieht, drüber diskutieren bringt häufig was.

    GG 4250
    ... was soll da eine Function oder gar UDF denn leisten? Und dann auch noch in einer "ordentlichen" Programmiersprache, die Huddel eben gar nicht können soll?
    Eine 4 Byte Integer hat einen Wertebereich von −2.147.483.648 bis 2.147.483.647. Also speichert man die Kundennummer als int. Für die 5 stellige Alpha Welt (COBOL) macht man eine DDS LF, die behauptet, dass das int Feld CHAR 4 ist (bleibt noch das eine Byte dazu zu huddeln). Wenn SAP keine int mag, dann kann man das Feld ja in einer SQL View als dec(8, 0) vorzeigen.

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

  10. #10
    Registriert seit
    Aug 2006
    Beiträge
    2.114
    Hallo *all,
    jetzt noch mal ganz langsam.
    Die Aufgabestellung war bisher:
    Nimm die Daten aus unserem Warenwirtschaftssystem von der AS/400 und erstelle damit Schnittstellendaten für unseren Außendienst (RP-Trade auf dem IPad).
    Hat jahrelang mit einem Cobol-Programm gut funktioniert.

    Dann kam ja jetzt letztes Jahr SAP und damit wurde dann alles besser und den alten Mist brauchte man nicht mehr.
    Kaum ein Jahr später stellte man fest das der alte Mist doch eigentlich gut war und man es gerne wieder haben möchte.

    Also muß ich jetzt die Konditionen der Verkaufspreise in eine Schnittstelle packen.
    Jeder Kunde kann seine eigene Preisliste haben, einem Verband angehören oder nur z.B. Großhandelspreise haben.
    Sprich im Kundenstamm wird hinterlegt ob Kundenpreisliste oder z.B. GH-Preisliste.
    Bei ca. 1.500 Kunden mit jetzt 8stelligen Kundennummern muß ich also ein Mapping machen von 8 Stellen auf max 5 Stellen. Da ich es früher mit Cobol und Hex gemacht habe war das jetzt auch mein erster Ansatz. Aber in der Diskussion hat sich ja nun rausgestellt das ein normale Mapping von z.B.

    Kunden-Nr 19645978 -> Preisliste 1
    Kunden-Nr 68954556 -> Preisliste 2
    vollkommen ausreichend ist.

    Da das SAP-System bei einem bekannten Großbäcker läuft und ich leider da meine ABAP-Kenntnisse nicht anbringen darf, hole ich mir die Daten auf meine geliebte AS/400 und erstelle mir dort die Schnittstellendatei.
    Und mein erster Ansatz war jetzt SQL, da ich den Aufbau der Daten für die Schnittstellen (Kundenstamm, Artikelstamm, Preislisten) mit Views erstelle die dann per cpy.. als Textdatei dem RP-Trade Server vorwerfe.

    So langer Rede kurzer Sinn ich finde es schon schön was mit SQL so alles geht. Schade nur das man sich das alles selber beibringen muß. (Forum sei Dank auch Hilfe bekommt)

    GG 4249

  11. #11
    Registriert seit
    Aug 2001
    Beiträge
    2.928
    Wenn ich das richtig verstehe, konvertierst Du die dezimalen Kunden-Nr. in Integer-Werte und speichest den HEX-Wert des Integers in einer Umsetzungstabelle.

    Soweit so einfach! Aber es gibt keinen direkten Weg (zumindest ist mir keiner bekannt) aus dem Hex-Wert wieder einen Integer-Wert zu machen.

    ... allerdings was man nicht hat, schreibt man sich einfach.
    Hier eine kleine Funktion (Hex-Konverter für Integer), die den bereits nach Hex konvertierten Integer-Wert empfängt und in einen numerischen Wert konvertiert.

    Code:
    Create or Replace Function YourSchema.ConvertHexToInt
             ( ParHexInteger VarChar(11) Default '0' )
           Returns Integer
           Language SQL
           Modifies SQL Data
           Deterministic
           Specific CvtHex2Int
           Called on NULL Input
    
           Set Option
               DATFMT  = *ISO,
               DBGVIEW = *SOURCE,
               DECMPT  = *COMMA,
               TIMFMT  = *ISO
    
     Begin
       Declare LocPower      Integer  Not NULL Default 0;
       Declare LocCounter    Integer  Not NULL Default 0;
       Declare RtnValue      Integer  Not NULL Default 0;
    
       Set ParHexInteger = Trim(Leading '0' from Trim(ParHexInteger));
       If Length(ParHexInteger) = 0 Then Return 0;
       End If;
    
       If Translate(Upper(ParHexInteger), ' ', '0123456789ABCDEF') > ''
          Then Signal SQLSTATE 'XER01' Set Message_Text = 'Invalid characters';
       End If;
    
       Set LocPower = Length(ParHexInteger);
    
       BegLoop: Loop
           Set LocPower = LocPower - 1;
           If LocPower < 0 Then Leave BegLoop;
           End If;
    
           Set LocCounter = LocCounter + 1;
    
           Set RtnValue = RtnValue +
                          Case Upper(Substr(ParHexInteger, LocCounter, 1))
                               When 'A' Then 10
                               When 'B' Then 11
                               When 'C' Then 12
                               When 'D' Then 13
                               When 'E' Then 14
                               When 'F' Then 15
                               Else Substr(ParHexInteger, LocCounter, 1)
                          End * 16 ** LocPower;
        End Loop;
    
        Return RtnValue;
     End;
    SQL-Funktionen und Stored Procedures kann man im übrigen mit dem in Client Access oder Access Client Solutions (ACS) integrierten Debugger debuggen.
    Um den SQL-Code debuggen zu können, muss ein SET OPTION Statement mit DBGVIEW = *SOURCE (s. mein Beispiel) integriert werden.
    Über STRSQL zu debuggen ist schwierig und wenn kann man lediglich den generierten C-Code debuggen.

    Ansonsten dürftest Du mit Deiner Funktion Probleme bekommen, wenn Du versuchst den alphanumerischen HEX-Wert in eine numerische/Integer Variable auszugeben. Spätestens beim 1. A wird ein NULL-Wert ausgegeben.

    Birgitta
    Birgitta Hauser

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

  12. #12
    Registriert seit
    Feb 2001
    Beiträge
    20.696
    Es wäre nicht das erste Mal, wenn man für Schnittstellen den falschen Weg beschritten hätte.
    Wie du ja nun selbst festgestellt hast, ein Mapping per Zusatztabelle ist hier der einfachste Weg.
    Per View kann an die Daten dann zusammensuchen.
    Allerdings kann der CPYxxxIMPF leider nur PF's/Tables, so dass du per "create table MyExport as (select ...) die Schnittstelle aufbauen muss.
    Das hat zusätzlich aber auch den Vorteil, dass man die Daten filtern und neue Berechnungen durchführen kann, was der CPYxxx eben nicht kann.

    Statt Hex habe ich mal für einen anderen Kunden eine Umrechnung von Dezimal in 35-stelliges System (also nicht nur 16 Zeichen sondern 0-9 und A-Z, Kleinbuchstaben gingen nicht, da das DSPF nur Großbuchstaben zuließ) mit 3 Zeichen gemacht, also AAA = 000 bis 999 = 35*35*35-1, das hatte dann auch gereicht. Für deine 5 Stellen hätte es bis ca. 15,5Mio (35^5-1) auch genügt.
    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. SQL Satzaufbau V6R1
    By KingofKning in forum NEWSboard Programmierung
    Antworten: 4
    Letzter Beitrag: 05-04-17, 10:36
  2. V6R1 strdbg
    By KingofKning in forum NEWSboard Programmierung
    Antworten: 4
    Letzter Beitrag: 27-01-16, 09:59
  3. V6R1 Datensicherung
    By KingofKning in forum IBM i Hauptforum
    Antworten: 12
    Letzter Beitrag: 11-11-15, 10:40
  4. Umstieg V5R4 -> V6R1 die II
    By KingofKning in forum IBM i Hauptforum
    Antworten: 2
    Letzter Beitrag: 29-10-15, 08:32
  5. V6R1 Backlevel
    By KingofKning in forum IBM i Hauptforum
    Antworten: 3
    Letzter Beitrag: 16-09-15, 18:21

Berechtigungen

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