[NEWSboard IBMi Forum]
  1. #1
    Registriert seit
    Jan 2012
    Beiträge
    1.102

    UDTF mit optionalen Input-Parametern

    Hallo,
    ich möchte eine User Defined Table Function erstellen. Die SQL-UDTF soll ein RPGLE-Programm (in diesem Fall ein Serviceprogramm) aufrufen. Das haben wir alles schon oft gemacht und es klappt normalerweise. Jetzt haben wir die Besonderheit, dass wir der UDTF variabel viele Input-Parameter mitgeben möchten. Ich habe deshalb mehrere SQL-Funktionen mit dem gleichen Namen und den unterschiedlichen Parametern erstellt. Alle verweisen auf dasselbe RPG-Programm. (so haben wir das bei normalen UDFs (nicht UDTFs!) auch schon oft gemacht.

    Im RPG werden ja viel mehr Parameter deklariert als in der SQL-UDTF. Also die Input-Werte der SQL-UDTF, dann die zurückzugebenden Spalten, dann für alle Parameter die Null-Indikatoren und dann noch die Standard-Statusvariablen (z.B. Scratchpad).
    Die Besonderheit liegt im RPG jetzt darin, dass die optionalen Parameter (meiner Meinung nach) innerhalb der Gesamt-Parameterdeklaration stehen müssen und nicht, wie üblich, am Ende. Ich habe also die optionalen Parameter am Ende der Input-Parameter eingetragen. Das Programm lässt sich kompilieren. Aber beim Aufruf über die SQL-Funktion gibt es Runtime-Fehler, weil nicht alle Parameter übergeben wurden.

    Deshalb die wichtigste Frage: Geht das überhaupt? Also UDTF mit RPGLE und optionalen Parametern.
    Falls ja: Wo in der Parameterliste müssen die optionalen Parameter stehen und wie werden sie deklariert? (Ich habe das ja mit *OMIT gemacht).

    Vielen Dank im Voraus.

    Dieter

  2. #2
    Registriert seit
    Mar 2002
    Beiträge
    5.286
    ... das OMIT sorgt doch nur dafür, dass der Compiler beim Aufrufer den Prototyp akzeptiert. Im RPG programm muss man sich schon drum kümmern, was man übergeben bekommt (%null, &parms und monitor stehen dort zur Verfügung)

    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/

  3. #3
    Registriert seit
    Feb 2001
    Beiträge
    20.207
    Ja, das mit dem Überladen der Funktion ist ja korrekt, allerdings ist der Weg dann ein anderer für die Aufrufe (synmolische Beschreibung):

    MyFunction(P1, P2, P3) <= Hauptfunktion
    { MyILERpg (P1, p2, P3) }

    MyFunction(P1, P2) <= Überladen
    { MyFunction(P1, P2, NULL) }

    MyFunction(P2) <= Überladen
    { MyFunction(NULL, P2, NULL) }

    Alternativ geht es natürlich auch mit verschiedenen Parametertypen:
    MyFunc(P1Char, P1Num)

    MyFunc(P1Char)
    { MyFunc(P1Char, NULL) }

    MyFunc(P1Num)
    { MyFunc(NULL, P1Num) }

    D.h.:
    Du hast eine Grund-SQL-Funktion/Prozedur mit allen Parametern und Verweis auf dein RPG.
    Alle weiteren SQL-Funktionen/Prozeduren gleichen Namens und anderer Signatur rufen die Grundfunktion-SQL-Funktion/Prozedur (Nicht das RPG!) auf und belegen die fehlenden Parameter mit NULL oder auch einem beliebigen anderen Default-Wert.

    Der Aufruf des RPG's im SQL-Mode (den man verwenden sollte):
    - alle Parameter (P1, P2, ...)
    - Returnwert
    - NullFlages für alle Parameter
    - NullFlag des Returnwertes
    - SQL-Variablen (Name, Diagnose, ...)

    Wie du siehst, lassen sich dem RPG daher aus SQL keine verschiedenen Parameter unterjubeln.
    Du kannst natürlich ein wenig mit Pointern und Rechenlogik spielen:
    Per %Parms() bekommst du die Anzahl Parameter.
    Davon ziehst du die letzen 3-4 SQL-Parameter ab.
    Der Rest muss nun eine Geradzahlige Anzahl sein.
    Die 1. Hälfte sind Parameter + Return, die 2. Hälft die NULL-Flags.

    Was machst du dann aber per MyFunc(P1Num) und MyFunc(P1Char)?
    In ILERPG lässt sich der Feldtyp und die Feldlänge der Übergabe leider nicht abfragen.
    Dies ist OOP-Sprachen vorbehalten (durch strenge Typisierung).

    Übrigens:
    Wenn man sich die Definition eines fertigen Moduls/Programms ansieht, so steht da
    Anzahl Parameter 0 - 400!
    D.h., zur Laufzeit wird nicht geprüft, wieviele Parameter tatsächlich übergeben werden oder von der Prozedur erwartet werden.
    OMIT definiert nur für den Compiler, dass er bei fehlender Kodierung des Parameters automatisch NULL-Pointer übergibt.
    D..h., ein Prototyp definiert die Parameter, wobei die letzten Omitted sein können.
    Bei einer verkürzten Parameterliste, hängt der Compiler eben NULL-Adressen einfach an.

    Ein externer Aufruf aus SQL (dynamischer CALL, CALLPRC) macht das aber nicht.
    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 2003
    Beiträge
    1.508
    Hallo Dieter,

    habt ihr euch schon in SQL das Thema "Named Parameter" angesehen?
    In SQL könnt ihr die Parameter direkt angeben die ihr verwenden wollt.
    Wichtig ist nur, dass ihr beim Erstellen der SQL Funktion korrekte Defaultwerte für alle Parameter setzt die vielleicht nicht benutzt werden.

    SELECT * FROM TABLE(QSYS2.ACTIVE_JOB_INFO(SUBSYSTEM_LIST_FILTER => 'QUSRWRK')) x

    lg Andreas

  5. #5
    Registriert seit
    Feb 2001
    Beiträge
    20.207
    Immer eine Frage des Releases.
    Natürlich kann ich mir die Überladungen sparen, wenn ich für nicht benötigte Parameter NULL angebe. Da weiß man zumindest, was der Verwender wirklich will.
    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

  6. #6
    Registriert seit
    Aug 2001
    Beiträge
    2.869
    Zitat Zitat von Fuerchau Beitrag anzeigen
    Immer eine Frage des Releases.
    Natürlich kann ich mir die Überladungen sparen, wenn ich für nicht benötigte Parameter NULL angebe. Da weiß man zumindest, was der Verwender wirklich will.
    Falls Du damit auf die Antwort von Andreas anspielst, ... solltest Du Dir mal wirklich die Default-Werte, die bei Stored Procedure und User Defined (Table) Function Parametern angegeben werden können anschauen.

    Bei dieser Technik können für Input-Parameter Default-Werte (und nicht nur NULL-Werte) definiert werden. Werden Input-Paramter, für die Default-Werte definiert wurden nicht übergeben, werden anstelle der Parameter die Default-Werte an die Stored Procedure oder User Defined (Table) Function übergeben.

    Man kann nicht nur Parameter weglassen, man kann auch über "Argument Listen" einzelne Parameter benennen (=Named Parameters) und diesen beim Aufruf einen Wert zuweisen. Wird ein Parameter benannt, so muss der Parameter-Name, der beim Erstellen oder Registrieren der Routine definiert wurde angegeben werden. Auf den Parameter-Name muss => folgen und im Anschluss der eigentliche Parameter-Wert oder Variable (s. Beispiel von Andreas).
    Werden die Input Parameter benannt, so genügt es lediglich die benötigten Parameter (bzw. die von den Default-Werten abweichenden Parameter-Werte) zu übergeben. Die Reihenfolge in der die benannten Parameter angegeben werden, spielt dabei keine Rolle.

    Diese Technik wurde mit einem Technologie Refresh eingeführt und von Release 7.1 an aufwärts verfügbar.

    Noch eine Erinnerung an alle diejenigen, die Release 7.1 oder älter einsetzten. Der offizielle Support von IBM für Release 7.1 endet am 30.04.2018. (für ältere Releases gibt es von IBM keinerlei Support mehr)
    Die Neuerungen, die gerade auf der Common Herbst Konferenz in den USA für den nächsten Technology Refresh announced wurden (und das sind gerade im Bereich von SQL und Datenbank nicht wenige), werden nur für Release 7.2 und 7.3 bereitgestellt.

    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.207
    Das mit den Defaults für Parameter wurde bereits oben erwähnt und manche OO-Sprachen kennen das auch.
    Ich habe ja nur gesagt, dass man Funktionen/Prozeduren mit allen Parametern auch mit individuellen Defaults(=Konstanten, NULL) aufrufen kann.
    Bei solchen Konstrukten (Defaults/Überladungen) bedarf es schon genauer und guter Dokumentation, damit man nicht auf die Nase fällt.
    Seit Einführung der globalen SQl-Variablen (V7R1?) falle ich leider immer wieder auf die Nase, da der Compiler mir nur noch in seltenen Fällen Tippfehler als Fehler rauswirft und ich mich erst zur Laufzeit Frage, warum was nicht läuft.
    Vielleicht kann man das ja zur Compilezeit irgendwie als Warnung oder mit Heruntersetzen der Bewertung anpassen damit der Compiler Fehler wieder meldet.
    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
    Mar 2002
    Beiträge
    5.286
    ... ich denke, dass man da noch etwas tiefer einsteigen muss:
    Überladung und optionale Parameter sind zwei verschiedene Dinge, wobei Überladung der stärkere Mechanismus ist, weil bei der Verwenung bereits zur Compiletime geprüft wird und die zu übergebenden Parameter keiner Anordnungsbedingung unterliegen.
    Namensparameter sind zwar sehr flexibel, was aber gerade die Prüfbarkeit zur Compilezeit einschränkt; zudem muss der Verwender mehr Wissen über die innere Implementierung haben.

    Was das ursprüngliche Problem angeht (Überladung einer external (RPG) UDTF) ist es wohl am einfachsten (und damit auch am besten), die Überladung in der RPG Implementierung mit abzubilden und mehrere RPG Aufrufpunkte zu haben (1 : 1 zu den Überladungen). Hier bietet sich dann eher ein SRVPGM an. Die Verzweigung kann dann wieder in einer Implementierung münden, die den Hauptteil der Logik einthält.

    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/

  9. #9
    Registriert seit
    Jan 2012
    Beiträge
    1.102
    Vielen Dank für alle Antworten. Ich habe viel neues erfahren. Mein eigentliches Problem war ja die Fragestellung, weshalb die im RPG erwarteten optionalen Parameter nicht rüberkamen. Auf die simple Idee, im SQL Null anzugeben, bin ich ich nicht gekommen.
    Die Sache mit den benannten Parametern war mir ebenfalls nicht bewusst. Ich habe die Syntax im SQL in den neuen mitgelieferten Funktionen zwar schon ein paar Mal gesehen, aber mir war eigentlich nicht richtig klar, dass damit eine Parameterbenennung realisiert wird. Danke auch für diesen Ansatz.

    Ich wünsche allen einen guten Start in die neue Woche.
    Dieter

  10. #10
    Registriert seit
    Aug 2003
    Beiträge
    1.508
    Und falls wer meint, dass zum Compile-Zeitpunkt keine Prüfung stattfindet, bitte es einfach mal ausprobieren.
    Der Fehler ist dann nämlich:
    The CALL statement or function invocation includes named argument &1 which does not exist for routine &2 in schema &3.

  11. #11
    Registriert seit
    Mar 2002
    Beiträge
    5.286
    ... zwischen nix prüfen und wenig prüfen können, gibt es wesentliche Unterschiede - nur so am Rande, der Präzision halber, erwähnt.
    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.207
    Ich meinte ja auch die Nichtprüfung von Spaltennamen in Select und Where-Klauseln, die nun leider erst zur Laufzeit passieren, da alle nicht gefundenen Namen, die nicht explizit benötigt werden, für globale Variablen gehalten werden. Und das schlägt erst zurLaufzeit an. Da reicht schon mal das Vergessen eines Doppelpunktes.
    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. input/output feld dspf --> automatisch aus Feld springen
    By _MG_ in forum NEWSboard Programmierung
    Antworten: 2
    Letzter Beitrag: 15-09-17, 16:02
  2. Logging FTP-Input
    By Flappes in forum IBM i Hauptforum
    Antworten: 19
    Letzter Beitrag: 24-03-17, 14:26
  3. SQL mit enthaltenen Parametern innerhalb von CL's
    By _MG_ in forum NEWSboard Programmierung
    Antworten: 14
    Letzter Beitrag: 12-12-15, 13:07
  4. Frage zu RPG: Aufruf RPG-Programm mit Parametern
    By hs in forum IBM i Hauptforum
    Antworten: 14
    Letzter Beitrag: 09-10-01, 13:06

Berechtigungen

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