Kontext in benutzerdefinierten Funktionen
Benutzerdefinierte Funktionen (UDFs = User Defined Functions) sind eigens erstellte Funktionen, die in ein Mapping eingebettet werden, in denen Sie die Inputs, Outputs und Verarbeitungslogik definieren. Jede benutzerdefinierte Funktion kann dieselben Komponentenarten wie ein Hauptmapping, darunter auch Webservices und Datenbanken, enthalten.
Wenn eine UDF eine Datenbank oder einen Webservice enthält und es sich bei den Input-Daten für die UDF um eine Sequenz aus mehreren Werten handelt, wird die UDF standardmäßig mit jedem Input-Wert aufgerufen, was einen Datenbank- oder Webservice-Aufruf zur Folge hat. |
Das oben beschriebene Verhalten ist unter Umständen in Mappings, in denen die UDF wirklich so oft, wie Input-Werte vorhanden sind, aufgerufen werden muss, und in denen es keine andere Methode gibt, akzeptabel.
Wenn Sie das oben beschriebene Verhalten vermeiden möchten, können Sie die UDF so konfigurieren, dass sie, selbst wenn sie als Input eine Sequenz von Werten erhält, nur einmal aufgerufen wird. Normalerweise empfiehlt sich dies bei den UDFs, die an einer Gruppe von Werte ausgeführt werden, bevor sie ein Ergebnis zurückgeben (z.B. Funktionen, die Durchschnittswerte oder Summen berechnen).
Eine UDF so zu konfigurieren, dass sie im selben Funktionsaufruf mehrere Input-Werte akzeptiert, ist dann möglich, wenn es sich bei der UDF um eine reguläre UDF und nicht um eine "Inline"-UDF handelt (Nähere Informationen dazu finden Sie im Kapitel Benutzerdefinierte Funktionen.) Bei regulären Funktionen können Sie durch Aktivierung des Kontrollkästchens Input ist eine Sequenz definieren, dass der Input-Parameter eine Sequenz ist. Dieses Kontrollkästchen finden Sie in den Komponenteneinstellungen, die angezeigt werden, wenn Sie auf die Titelleiste eines Input-Parameters doppelklicken. Das Kontrollkästchen wirkt sich folgendermaßen darauf aus, wie oft die Funktion aufgerufen wird:
•Wenn Input-Daten mit einem Sequenz-Parameter verbunden werden, wird die benutzerdefinierte Funktion nur einmal aufgerufen und die vollständige Sequenz wird an die benutzerdefinierte Funktion übergeben.
•Wenn Input-Daten mit einem Nicht-Sequenz-Parameter verbunden werden, wird die benutzerdefinierte Funktion für jedes einzelne Datenelement in der Sequenz nur einmal aufgerufen.
Ein Beispiel dazu finden Sie im folgenden Demo-Mapping: <Dokumente>\Altova\MapForce2025\MapForceExamples\InputIsSequence.mfd.
Im obigen Mapping sehen Sie ein Beispiel für einen typischen Fall einer UDF, die an einer Gruppe von Werten ausgeführt wird und für die daher alle Input-Werte in einem einzigen Aufruf abgerufen werden müssen. Die benutzerdefinierte Funktion Calculate gibt hier die Temperaturminima, -maxima und die Durchschnittstemperaturen zurück. Die Input-Daten dafür stammen aus einer XML-Quelldatei. Die erwartete Mapping-Ausgabe sieht folgendermaßen aus:
<Temperatures> |
Wie gewöhnlich beginnt die Mapping-Ausführung beim obersten Datenelement der Zielkomponente (in diesem Beispiel YearlyStats). Um diesen Node zu befüllen, versucht das Mapping die Quelldaten aus der UDF zu holen, welche wiederum den Filter auslöst. Die Rolle des Filters ist es, nur Temperaturen aus dem Jahr 2008 an die UDF zu übergeben.
Für den Input-Parameter der UDF wurde das Kontrollkästchen Input ist eine Sequenz aktiviert (um dieses Kontrollkästchen zu sehen, doppelklicken Sie auf die Titelleiste der Funktion Calculate, um das Mapping der Funktion aufzurufen. Doppelklicken Sie anschließend auf die Titelleiste des Input-Parameters). Wie zuvor erwähnt, wird aufgrund der Option Input ist eine Sequenz die vollständige Sequenz der Werte als Input an die Funktion geliefert und die Funktion wird nur einmal aufgerufen.
Wäre das Kontrollkästchen Input ist eine Sequenz nicht aktiviert, wäre die UDF für jeden Wert in der Quellkomponente einzeln aufgerufen worden, sodass die Minima, Maxima und Durchschnittstemperaturen für jeden Wert einzeln berechnet würden, wodurch eine falsche Ausgabe erzeugt würde.
Durch Anwendung derselben Logik in komplexeren UDFs, die Datenbank- oder Webservice-Aufrufe enthalten, kann die Ausführung unter Umständen optimiert und unnötige Datenbank- oder Webservice-Aufrufe können vermieden werden. Bedenken Sie jedoch, dass das Kontrollkästchen Input ist eine Sequenz keinen Einfluss darauf hat, was mit der Wertesequenz nach ihrem Eintritt in die Funktion passiert, d.h. die eingehende Wertesequenz könnte auch mit dem Input eines Webservice verbunden werden, wodurch dieser mehrmals aufgerufen würde. Werfen Sie einen Blick auf das folgende Beispiel:
Die oben gezeigte UDF erhält aus dem externen Mapping eine Sequenz von Werten. Die an den Input-Parameter gelieferten Daten stammen in diesem Fall aus einer Datenbank. Für den Input-Parameter wurde die Option Input ist eine Sequenz aktiviert, daher wird die gesamte Sequenz in einem einzigen Aufruf an die Funktion geliefert. Mit der Funktion sollen mehrere quantity-Werte addiert und an einen Webservice gesendet werden. Es wird genau ein Webservice-Aufruf erwartet. Bei Ausführung des Mappings wird der Webservice jedoch fehlerhafter Weise mehrmals aufgerufen. Der Grund dafür ist, dass der Request-Input des Webservice eine Sequenz von Werten anstatt eines einzigen Werts erhält
Um dieses Problem zu beheben, verbinden Sie den Request-Input des Webservice mit dem Ergebnis (result) der sum-Funktion. Das Ergebnis der Funktion ist ein einziger Wert, sodass auch der Webservice nur einmal aufgerufen wird:
Normalerweise erzeugen Aggregatsfunktionen wie sum, count, einen einzigen Wert. Wenn es jedoch eine übergeordnete Verbindung gibt, die dies zulässt, können sie auch, wie im Beispiel: Ändern des Parent-Kontexts näher beschrieben, eine Sequenz von Werten erzeugen. |