User-defined functions (UDFs) are custom functions embedded into the mapping, where you define the inputs, outputs, and processing logic. Each user-defined function may contain the same component kinds as a main mapping, including Web services and databases.
By default, if a UDF contains a database or a Web service component, and if the input data to the UDF is a sequence of multiple values, then each input value will call the UDF and consequently will result in a database or Web service call.
The behavior above may be acceptable for those mappings where you really need the UDF to be called as many times as there are input values and there is simply no other alternative way.
If you do not want the above to happen, you can configure the UDF so that it is called only once even if gets a sequence of values as input. You will typically want to do this for those UDFs that operate on a set of values before they can return (such as functions that calculate averages or totals).
Configuring a UDF to accept multiple input values in the same function call is possible if the UDF is of type "regular", not "inlined". (For details, see the User-Defined Functions chapter.) With regular functions, you can specify that the input parameter is a sequence by selecting the Input is a sequence check box. This check box is visible on the component settings, after you double-click the title bar of an input parameter. The check box affects how often the function is called, as follows:
•When input data is connected to a sequence parameter, the user-defined function is called only once and the complete sequence is passed into the user-defined function.
•When input data is connected to a non-sequence parameter, the user-defined function is called once for each single item in the sequence.
For an example, open the following demo mapping: <Documents>\Altova\MapForce2020\MapForceExamples\InputIsSequence.mfd.
The mapping above illustrates a typical case of a UDF that operates on a set of values and thus requires all the input values in one call. Specifically, the Calculate user-defined function returns the minimum, maximum and average temperatures, taking as input data from a source XML file. The expected mapping output is as follows:
As usual, the mapping execution begins with the top item of the target component (YearlyStats, in this example). To populate this node, the mapping attempts to obtain source data from the UDF, which in its turn, triggers the filter. The filter's role in this mapping is to pass onto the UDF only temperatures from year 2008.
The check box Input is sequence was selected for the input parameter of the UDF (To view this check box, double-click the title bar of the Calculate function to enter the function's mapping; then double-click the title bar of the input parameter). As mentioned before, the Input is sequence option causes the complete sequence of values to be supplied as input to the function and the function is called only once.
Had the Input is sequence check box not been selected, the UDF would have been called for each value in the source. As a result, the minimum, maximum and average would be calculated for each single value individually and incorrect output would be produced.
By applying the same logic in more complex UDFs that include database or Web service calls, it may be possible to optimize the execution and avoid unnecessary calls to the database or Web service. Nevertheless, be aware that the Input is sequence check box does not control what happens to the sequence of values after it enters the function. In other words, there is nothing to prevent you from connecting the incoming sequence of values to the input of a Web service and thus call it multiple times. Consider the following example:
The UDF illustrated above receives a sequence of values from the external mapping. Specifically, the data supplied to the input parameter originates from a database. The input parameter has the option Input is sequence selected, so the entire sequence is supplied to the function in one call. The function is supposed to add up multiple quantity values and post the result to a Web service. Exactly one Web service call is expected. However, the Web service will be incorrectly called multiple times when the mapping runs. The reason is that the Request input of the Web service receives a sequence of values, not a single value.
To fix this problem, connect the Request input of the Web service to the result of the sum function. The function produces one single value, so the Web service will also be called once:
Normally, aggregate functions like sum, count, etc produce a single value. Nevertheless, if there is a parent connection that allows it, they may produce a sequence of values as well, as described further in the Example: Changing the Parent Context.