On peut aussi mettre en oeuvre des UDF dans un langage de haut niveau (HLL) comme
le RPG ILE.
Figure 2, les définitions de tables s'inspirent d'une situation concrète rencontrée
sur un site client. La table des opérations de fabrication (Mfg_Oper) contient
toutes les commandes, les étapes nécessaires pour les
Création d’une UDF externe
honorer, un temps standard
nécessaire pour fabriquer une pièce (exprimé en temps par pièce) et un salaire
horaire standard. La table d’activité atelier (Shop_Act) contient des informations
associées comme par exemple le temps réel passé, la date, la quantité produite,
et les employés ayant travaillé sur les commandes. Il a fallu écrire des rapports
sur les employés qui travaillaient sur les commandes, les montants dépensés, et
les écarts entre les temps standard et réel.
Le hic est que le temps enregistré dans la table d’activité atelier (Shop_Act)
peut être exprimé en minutes, heures, dixièmes d’heures, ou d’autres manières.
Un code base de temps dans la table des opérations indique les unités servant
à enregistrer le temps (H = heures, M = minutes, C = opération externe, par exemple).
En revanche, les tarifs sont toujours exprimés en dollars par heure. Il faut donc,
pour que les calculs soient homogènes, convertir tous les temps en heures. De
plus, quand on calcule les heures standard, il faut multiplier le temps standard
par la quantité produite, parce que le temps standard sur l’opération est exprimé
en temps/pièce. Figure 3, les calculs de conversion en heures apparaissent en
utilisant des expressions Case. Notons à quel point les multiples expressions
Case rendent cette instruction complexe.
Ces expressions Case se prêtent parfaitement à un remplacement par une UDF. La
figure 4 présente l’instruction Create Function utilisée pour créer l’UDF CvtHours.
Je définis deux paramètres, code base de temps (Tb_Code) et quantité en temps
(Time_Qty), pour l’UDF, et l’UDF renvoie les heures. Notons les options External
Name, Returns Null on Null Input, Language, No SQL et Parameter Style.
External Name indique le nom effectif de l’objet programme et
de sa bibliothèque. Cette option est obligatoire pour tout langage autre que SQL.
Ici, on peut aussi indiquer le mot-clé External tout seul, auquel cas le nom du
programme externe est supposé être le même que celui du nom de la fonction. Le
système commence à rechercher le programme externe quand on exécute l’instruction
Create Function. La manière dont il recherche un nom non qualifié dépend de l’option
d’appelation utilisée.
Returns Null on Null Input demande à SQL/400 de ne pas exécuter
l’UDF si l’un des paramètres d’entrée est Null. Si un ou plusieurs paramètres
sont Null, le résultat de CvtHours sera lui aussi Null.
Language RPGLE indique que l’UDF est une fonction externe écrite
en ILE RPG.
No SQL est l’une des options de l’ensemble suivant : No SQL,
Reads SQL Data, Modifies SQL Data et Contains SQL. Ces mots-clés disent à SQL/400
si le programme HLL contient des instructions SQL et, si oui, de quel type. Le
programme CvtHours ne contenant pas de SQL, j’ai indiqué No SQL.
Parameter Style détermine la manière dont les paramètres seront
transmis à l’UDF. Il existe quatre options, SQL, DB2SQL, Simple et General, mais
je m’en tiendrai à SQL.
Figure 7 Paramètres requis pour une UDF externe identifiant SQL comme style de paramètre |
||
Description du paramètre | In et/ou Out | Type de données |
Les N premiers paramètres sont les paramètres en entrée indiqués sur l’instruction Create Function |
In | Ces paramètres doivent correspondre (en type et en taille) à la liste des paramètres de l’instruction Create Function |
Un paramètre pour le résultat de la fonction | Out | Ce paramètre doit correspondre au type et à la taille de données indiqués au mot-clé Create Function Returns |
N paramètres comme variables d’indicateurs nuls pour chaque paramètre en entrée |
In | Small Integer (binaire sur deux octets) |
Une variable d’indicateur nul pour le résultat | Out | Small Integer (binaire sur deux octets) |
Un paramètre pour SQL State | In/Out | CHAR(5) |
Le nom de la fonction entièrement qualifié | In | CHAR(139) |
Le nom spécifique | In | CHAR(128) |
Texte d’avertissement ou de message | In/Out | VARCHAR(70) |
La figure 5 présente la mise en oeuvre RPG ILE de l’UDF CvtHours, qui remplace
les expressions SQL Case utilisées pour convertir la quantité de temps en heures.
La figure 6 contient un exemple d’instruction SQL qui appelle CvtHours. La table
de la figure 7 donne la listes des paramètres nécessaires quand on utilise un
programme HLL pour mettre en oeuvre une UDF et qu’on indique SQL comme style de
paramètre.
Dans la liste des paramètres *Entry du programme (en A, figure 5), les paramètres
en entrée de la fonction (code base de temps (tbcde) et quantité de temps (time))
sont les premiers sur la liste, suivis du résultat des heures (heures) puis des
variables d’indicateur null pour chacun. Les indicateurs null sont de petits entiers
servant à indiquer si un paramètre est transmis ou renvoyé comme null. Une valeur
d’indicateur null non négative indique une valeur non-null et une valeur négative
indique null.
Dans notre exemple, l’UDF ne sera pas appelée si l’un quelconque des paramètres
d’entrée est null, et donc le programme ne vérifie pas ces variables d’indicateur
null. En revanche, si l’UDF était appelable avec des paramètres null, la fonction
devrait vérifier ces variables d’indicateur pour déterminer si les paramètres
ont été transmis comme null. De même quand la fonction doit renvoyer null, la
variable d’indicateur null résultante (hours_ind dans ce cas) doit être réglée
sur une valeur négative value (-1, par exemple).
Les quatre derniers paramètres requis sont SQL_State, Function_Name, Specific_Name
et Msg_Text. SQL_State et Msg__Text communiquent des informations d’erreur et
d’avertissement provenant de l’UDF et destinées à l’application SQL hôte. Quant
à Function_Name et Specific_Name, contentons-nous pour l’instant de savoir les
définir.
La section de code commence après la liste des paramètres. Une instruction Select
effectue la conversion de temps.
Le dernier cas de l’instruction Select est particulièrement intéressant parce
qu’il traite une condition d’erreur. Si l’UDF reçoit un code de temps invalide
(le cas Other), elle renvoie une erreur via le paramètre SQL_State.
Références SPL
Articles parus dans NEWSMAGAZINE Publications IBM |
Téléchargez cette ressource
Comment sécuriser une PME avec l’approche par les risques ?
Disposant de moyens financiers et humains contraints, les PME éprouvent des difficultés à mettre en place une véritable stratégie de cybersécurité. Opérateur de services et d’infrastructures, Naitways leur propose une approche pragmatique de sécurité « by design » en priorisant les risques auxquelles elles sont confrontées.