[NEWSboard IBMi Forum]
  1. #1
    Registriert seit
    Dec 2006
    Beiträge
    15

    externe UDF mit var. Parametern

    hallo forum

    ich möchte eine externe UDF nutzen, die mit unterschiedlichen Parametern aufgerufen werden kann. Ich registriere hierzu die gleiche Funktion mit den jeweiligen Paramtern mit SPECIFIC Name.

    Es soll immer das gleiche RPG-SRVPGM gecallt werden.

    Wie kann ich im RPG die Anzahl der übergebenen Parameter abfragen??

    %parms wird nicht unterstützt und liefert keinen Wert.

    Ich habe schon verschiedene Parameter-Styles probiert. Bei Parameter-Style SQL und DB2SQL kann ich zwar die NULL-Indicator ansprechen, bekomme aber keinen Wert in die Funktion exportiert. Das Ergebniss der Funktion ist immer NULL.

    Mit Paramter-Style GENERAL WITH NULLS habe ich das gleiche Problem.

    evtl. habt ihr einen Tip
    thx

    Hier die Funktionsdef.
    CREATE FUNCTION CMXLIB/GET_VK (
    FIRMA CHAR(3) ,
    ARTN DECIMAL(8, 0) ,
    FILIALE CHAR(3) ,
    GROP DECIMAL(2, 0) ,
    DATUM DATE, BRUNET varchar(1))
    RETURNS dec(9, 4)
    CAST FROM numeric(9, 4)
    LANGUAGE RPGLE
    SPECIFIC GET_VK1
    NOT DETERMINISTIC
    not fenced
    external action
    NO SQL
    PARAMETER STYLE GENERAL WITH NULLS
    EXTERNAL NAME 'CMXLIB/CAPI136R(GET_VK)';

    Hier das Parameterinterface vom RPG:
    p get_vk b export
    d get_vk pi 9s 4
    d p$firma 3
    d p$artn 8 0
    d p$filial 3
    d p$grop 2 0
    d p$datum d datfmt(*iso)
    d p$brunet 1 varying
    d p$firma_ni 2b 0
    d p$artn_ni 2b 0
    d p$filial_ni 2b 0
    d p$grop_ni 2b 0
    d p$datum_ni 2b 0
    d p$brunet_ni 2b 0
    d p$vkpr_ni 2b 0

  2. #2
    Registriert seit
    Mar 2002
    Beiträge
    5.287
    was soll das heißen %parms wird nicht unterstützt? beschreibe dein Problem mal genauer.

    Zitat Zitat von Peder Beitrag anzeigen
    hallo forum

    ich möchte eine externe UDF nutzen, die mit unterschiedlichen Parametern aufgerufen werden kann. Ich registriere hierzu die gleiche Funktion mit den jeweiligen Paramtern mit SPECIFIC Name.

    Es soll immer das gleiche RPG-SRVPGM gecallt werden.

    Wie kann ich im RPG die Anzahl der übergebenen Parameter abfragen??

    %parms wird nicht unterstützt und liefert keinen Wert.

    Ich habe schon verschiedene Parameter-Styles probiert. Bei Parameter-Style SQL und DB2SQL kann ich zwar die NULL-Indicator ansprechen, bekomme aber keinen Wert in die Funktion exportiert. Das Ergebniss der Funktion ist immer NULL.

    Mit Paramter-Style GENERAL WITH NULLS habe ich das gleiche Problem.

    evtl. habt ihr einen Tip
    thx

    Hier die Funktionsdef.
    CREATE FUNCTION CMXLIB/GET_VK (
    FIRMA CHAR(3) ,
    ARTN DECIMAL(8, 0) ,
    FILIALE CHAR(3) ,
    GROP DECIMAL(2, 0) ,
    DATUM DATE, BRUNET varchar(1))
    RETURNS dec(9, 4)
    CAST FROM numeric(9, 4)
    LANGUAGE RPGLE
    SPECIFIC GET_VK1
    NOT DETERMINISTIC
    not fenced
    external action
    NO SQL
    PARAMETER STYLE GENERAL WITH NULLS
    EXTERNAL NAME 'CMXLIB/CAPI136R(GET_VK)';

    Hier das Parameterinterface vom RPG:
    p get_vk b export
    d get_vk pi 9s 4
    d p$firma 3
    d p$artn 8 0
    d p$filial 3
    d p$grop 2 0
    d p$datum d datfmt(*iso)
    d p$brunet 1 varying
    d p$firma_ni 2b 0
    d p$artn_ni 2b 0
    d p$filial_ni 2b 0
    d p$grop_ni 2b 0
    d p$datum_ni 2b 0
    d p$brunet_ni 2b 0
    d p$vkpr_ni 2b 0
    AS400 Freeware
    http://www.bender-dv.de
    Mit embedded SQL in RPG auf Datenbanken von ADABAS bis XBASE zugreifen
    http://sourceforge.net/projects/appserver4rpg/

  3. #3
    Registriert seit
    Feb 2001
    Beiträge
    20.246
    Das Problem ist da eher wohl, dass du die Position des Parameters "Specific Name" feststellen musst.

    Die Frage ist eher, sind tatsächlich die Anzahl Paramter unterschiedlich oder nur die Ausprägung.

    Bei variablen Parametern musst du Pseudo-Variablen definieren und in Abhängigkeit der Funktion die Adressen der Parameter umsetzen:

    d MyInterface pi
    d P1 1
    D P2 1
    :
    :

    d P$FirmaPtr *
    D P$Firma 3 based(P$FirmaPtr)

    P$FirmaPtr = %addr(P1);

    Allerdings würde ich die Lösung einfacher gestalten:

    Je Funktion ein Aufruf einer Service-Routine, die wiederum die tatsächlich Funktion mit konkreten Parametern (ggf. castings) aufruft.

    Alles andere versteht ja fast keiner.
    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
    Aug 2001
    Beiträge
    2.875
    Hallo Peder,

    beim Parameter-Style General with NULL werden alle im Prototypen/Procedure Interface angegebene Parameter übergeben plus für jeden Parameter einen zusätzlichen NULL-Indicator. Aus diesem Grund werden ALLE in der Prozedur definierten Parameter übergeben. Für die nicht übergebenen Parameter wird ein NULL-Pointer übergeben.

    Aus diesem Grund musst Du Deine optionalen Parameter im Prototypen mit Options(*NoPass: *Omit) definiert werden. (In Deiner gegenwärtigen Parameter-Definition ist kein optionaler Parameter definiert, was auch mit ein Grund sein kann, warum %Parms keinen korrekten Wert liefert). Ebenfalls solltest Du bei Parameter-Style General with NULL eine Feldgruppe mit 5I 0 und sovielen Elementen wie Parameter übergeben werden können als letzten Parameter im Prototypen einfügen.

    Ob die optionalen Parameter übergeben sind oder nicht, kannst Du dann über %Addr(Param) abfragen.
    Wenn %Addr(Param) = *NULL, wurde der Parameter nicht übergeben. Alternativ kannst Du den NULL-Indikator für den entsprechenden Parameter prüfen. (< 0 entspricht NULL-Wert)

    Probleme könnten auch die Parameter-Felder mit 2B 0 bereiten, da SQL keinen entsprechenden Datentypen kennt. Sollten keine Probleme auftreten ist zuminest eine explizite oder implizite Typenkonvertierung erforderlich.

    Werden RPG-Funktionen als UDFs registriert, sollte darauf geachtet werden, das keine Typen-Konvertierung notwendig ist.

    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
    Dec 2006
    Beiträge
    15
    Hallo Leute,
    danke für die schnellen Antworten. Leider bin ich mit meinem Problem immer noch nicht weiter.

    Zitat Zitat von BenderD Beitrag anzeigen
    was soll das heißen %parms wird nicht unterstützt? beschreibe dein Problem mal genauer.
    %parms ist ein Element der ILE-Umgebung und gibt die Anzahl der übergebenen Parameter nur zurück, wenn der Caller diesen Wert zur Verfügung stellt. Das macht aber die UDF nicht. %parms ist immer -1, egal mit welchen Parametern ich die UDF auslöse.

    Zitat Zitat von Fuerchau
    Die Frage ist eher, sind tatsächlich die Anzahl Paramter unterschiedlich oder nur die Ausprägung.
    Nur die Anzahl der Parameter ist variabel. Die UDF soll den VK-Preis eines Artikels zu einem Termin liefern. Wird das Datum mitgegeben, soll es verwendet werden, ansonsten mit dem Tagesdatum gefüllt werden. Ich weiss, dass ich den Parameter immer mit 'current date' ersetzen kann, aber es geht mir eigentlich um das Wissen an sich, da ich zukünftig noch viele UDF's generieren möchte, und da habe ich dann andere Konstellationen. Ich hatte auch schon überlegt, mehrere Funktionen zu machen, aber das ist natürlich nur die zweitbeste Lösung ;-)

    Zitat Zitat von B.Hauser
    Ob die optionalen Parameter übergeben sind oder nicht, kannst Du dann über %Addr(Param) abfragen.
    Wenn %Addr(Param) = *NULL, wurde der Parameter nicht übergeben. Alternativ kannst Du den NULL-Indikator für den entsprechenden Parameter prüfen. (< 0 entspricht NULL-Wert)

    Probleme könnten auch die Parameter-Felder mit 2B 0 bereiten, da SQL keinen entsprechenden Datentypen kennt. Sollten keine Probleme auftreten ist zuminest eine explizite oder implizite Typenkonvertierung erforderlich.
    Birgitta, ich habe die Paramter so umgestellt, auch mit dem Array für den Null-Indikator. Die 2B o-Felder aus den Parametern waren meine Null-Indikatoren (aus der SQL-Style Definition).

    Habe folgende Änderung gemacht:
    d get_vk pi 9s 4
    d p$firma 3
    d p$artn 8 0
    d p$filial 3
    d p$grop 2 0
    d p$datum d datfmt(*iso)
    d p$brunet 1 varying
    d p$ni 5i 0 dim(7)

    p$ni ist das Null-Indikator-Array.
    habe auch das ganze mit OPTION(*nopass: *omit) probiert. Fakt ist, im Debug kann ich das Array p$ni nicht ansprechen, und auch die Abfrage %addr(p$datum) = *null läuft verkehrt, denn bei der Abfrage

    if %addr(p$datum) <> *null;
    §a4datv = %char(p$datum : *eur);

    wird der folgende eval versucht auszuführen, aber das geht dann schief, da der Wert kein gültiges Datum enthält.

    Evtl. habt ihr noch eine Idee.
    Thx

  6. #6
    Registriert seit
    Mar 2002
    Beiträge
    5.287
    wo hast du das mit den %parms her??? ohne das je ausprobiert zu haben (RPG unterstützt kein Overloading und wer das dann machen will, ist selbst dran schuld) vermute ich mal, dass %parms den Husten kriegt mit Parametern nach dem ersten fehlenden.
    Die Null Byte Array Lösung ist da defensiver, aber deine Abfrage ist Unfug statt %addr(feld) <> *null (denn übergeben wird hier ja ein Pointer, damit RPG das ab kann) musst du den Inhalt des entsrpechenden Null Indicators abfragen (und dann passt das Datum natürlich immer noch nur dann, wenn da kein Senf drinsteht).

    D*B

    Zitat Zitat von Peder Beitrag anzeigen
    Hallo Leute,
    danke für die schnellen Antworten. Leider bin ich mit meinem Problem immer noch nicht weiter.



    %parms ist ein Element der ILE-Umgebung und gibt die Anzahl der übergebenen Parameter nur zurück, wenn der Caller diesen Wert zur Verfügung stellt. Das macht aber die UDF nicht. %parms ist immer -1, egal mit welchen Parametern ich die UDF auslöse.



    Nur die Anzahl der Parameter ist variabel. Die UDF soll den VK-Preis eines Artikels zu einem Termin liefern. Wird das Datum mitgegeben, soll es verwendet werden, ansonsten mit dem Tagesdatum gefüllt werden. Ich weiss, dass ich den Parameter immer mit 'current date' ersetzen kann, aber es geht mir eigentlich um das Wissen an sich, da ich zukünftig noch viele UDF's generieren möchte, und da habe ich dann andere Konstellationen. Ich hatte auch schon überlegt, mehrere Funktionen zu machen, aber das ist natürlich nur die zweitbeste Lösung ;-)



    Birgitta, ich habe die Paramter so umgestellt, auch mit dem Array für den Null-Indikator. Die 2B o-Felder aus den Parametern waren meine Null-Indikatoren (aus der SQL-Style Definition).

    Habe folgende Änderung gemacht:
    d get_vk pi 9s 4
    d p$firma 3
    d p$artn 8 0
    d p$filial 3
    d p$grop 2 0
    d p$datum d datfmt(*iso)
    d p$brunet 1 varying
    d p$ni 5i 0 dim(7)

    p$ni ist das Null-Indikator-Array.
    habe auch das ganze mit OPTION(*nopass: *omit) probiert. Fakt ist, im Debug kann ich das Array p$ni nicht ansprechen, und auch die Abfrage %addr(p$datum) = *null läuft verkehrt, denn bei der Abfrage

    if %addr(p$datum) <> *null;
    §a4datv = %char(p$datum : *eur);

    wird der folgende eval versucht auszuführen, aber das geht dann schief, da der Wert kein gültiges Datum enthält.

    Evtl. habt ihr noch eine Idee.
    Thx
    AS400 Freeware
    http://www.bender-dv.de
    Mit embedded SQL in RPG auf Datenbanken von ADABAS bis XBASE zugreifen
    http://sourceforge.net/projects/appserver4rpg/

  7. #7
    Registriert seit
    Dec 2006
    Beiträge
    15
    Zitat Zitat von BenderD Beitrag anzeigen
    wo hast du das mit den %parms her???
    Hallo DBender:
    Hier der entsprechende Auszug aus dem RPG-Referenzhandbuch

    %PARMS returns the number of parameters that were passed to the procedure in which %PARMS is used. For the main procedure, %PARMS is the same as *PARMS.

    The value returned by %PARMS is not available if the program or procedure that calls %PARMS does not pass a minimal operational descriptor. The ILE RPG compiler always passes one, but other languages do not. So if the caller is written in another ILE language, it will need to pass an operational descriptor on the call. If the operational descriptor is not passed, the value returned by %PARMS cannot be trusted.
    wie schon geschrieben, wird %parms immer mit dem Wert -1 in das SRVPGM geliefert.

    Zitat Zitat von BenderD Beitrag anzeigen
    Die Null Byte Array Lösung ist da defensiver, aber deine Abfrage ist Unfug statt %addr(feld) <> *null (denn übergeben wird hier ja ein Pointer, damit RPG das ab kann) musst du den Inhalt des entsrpechenden Null Indicators abfragen (und dann passt das Datum natürlich immer noch nur dann, wenn da kein Senf drinsteht).
    Ich habe anstelle des %addr(feld) versucht die Null-Indicators anzusprechen, die sind aber nicht addressierbar (werden vermutlich auch nicht von der UDF gefüllt).

    Gruss
    Peder

  8. #8
    Registriert seit
    Mar 2002
    Beiträge
    5.287
    du solltest dir lieber mal die SQL Reference bezüglich der Parameterübergabe ansehen!
    Du hast eine Function mit 5 Parametern hin und einem zurück; daraus macht SQL (je nach Übergabe Art) so 5 bis 11 Parameter, die in der Reihenfolge, wie in der Function definiert (was anderes weiß sie ja nicht) die per Reference an die Procedure übergeben werden. Wenn du jetzt einen der Indicator abfragen willst, brauchst du für jede Procedure einen wrapper (siehe Baldur), oder du baust einen Wackelhaufen (von rückwärts erst mal mit %addr anfangen zu ermitteln ab wann da was kommt und dann die Parameter einzusortieren...)
    Im übrigen scheint hier ja noch was anderes faul zu sein, wenn ich dein letztes Posting verstehe, dann passt da ja die Anzahl der Parameter.

    D*B
    Zitat Zitat von Peder Beitrag anzeigen
    Hallo DBender:
    Hier der entsprechende Auszug aus dem RPG-Referenzhandbuch



    wie schon geschrieben, wird %parms immer mit dem Wert -1 in das SRVPGM geliefert.



    Ich habe anstelle des %addr(feld) versucht die Null-Indicators anzusprechen, die sind aber nicht addressierbar (werden vermutlich auch nicht von der UDF gefüllt).

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

Similar Threads

  1. Antworten: 11
    Letzter Beitrag: 18-07-16, 09:49
  2. UDF nicht verwendbar
    By Peder in forum IBM i Hauptforum
    Antworten: 4
    Letzter Beitrag: 06-12-06, 08:15
  3. Barcode in externe PRTF
    By Jump4738 in forum IBM i Hauptforum
    Antworten: 1
    Letzter Beitrag: 06-10-06, 15:08
  4. Externe Prozeduren/Bindeverzeichnisse
    By GraueEminenz in forum NEWSboard Programmierung
    Antworten: 2
    Letzter Beitrag: 18-07-06, 09:05
  5. SQL UDF Prob mit leeren Feldern
    By HACHIMAN in forum IBM i Hauptforum
    Antworten: 3
    Letzter Beitrag: 22-05-06, 09:48

Berechtigungen

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