Code source wiki de Indicateur NULL et base de données
Modifié par Julien EYMERY le 2015/08/31 11:50
Afficher les derniers auteurs
| author | version | line-number | content |
|---|---|---|---|
| 1 | ((( | ||
| 2 | = Introduction = | ||
| 3 | ))) | ||
| 4 | |||
| 5 | Ce document a pour but de décrire l'utilisation des valeurs (% style="color: rgb(255,102,0);" %)**NULL**(%%) en base de données. | ||
| 6 | |||
| 7 | {{hardis-info type="info" icon="true"}} | ||
| 8 | Seule une (% style="color: rgb(255,102,0);" %)**table**(%%) d'une base de données (% style="color: rgb(255,102,0);" %)**SQL**(%%) peut contenir des colonnes avec une valeur (% style="color: rgb(255,102,0);" %)**NULL**(%%). | ||
| 9 | {{/hardis-info}} | ||
| 10 | |||
| 11 | La présentation ci-dessous concerne les programmes (% style="color: rgb(255,102,0);" %)**Visual Adelia**(%%) et (% style="color: rgb(255,102,0);" %)**Web Adelia**(%%). | ||
| 12 | |||
| 13 | Si vous devez accéder à une base de données qui utilise des valeurs (% style="color: rgb(255,102,0);" %)**NULL**(%%) dans ses colonnes, vous devez alors mettre en place la gestion correspondante. | ||
| 14 | |||
| 15 | Cependant, nous décrirons un [[cas particulier valable pour des fonctions sur les colonnes en fin de page que nous vous invitons à lire>>doc:||anchor=casparticulier]]. | ||
| 16 | |||
| 17 | Pour cela, vous avez plusieurs aspects à prendre en compte : | ||
| 18 | * **[[Décrire>>doc:||anchor=decrire]]** dans votre (% style="color: rgb(255,102,0);" %)**modèle de données**(%%) Adelia les colonnes qui autorisent la valeur (% style="color: rgb(255,102,0);" %)**NULL**(%%) (Propriété conceptuelle / contrainte SQL ~= [NULL ; NULL WITH DEFAULT] ou bien Propriété logique / onglet complément / contrainte SQL ~= [NULL ; NULL WITH DEFAULT] ) | ||
| 19 | * **[[Vérifier>>doc:||anchor=verifier]]** que la colonne contient ou non une valeur (% style="color: rgb(255,102,0);" %)**NULL**(%%) après une lecture | ||
| 20 | * **[[Positionner>>doc:||anchor=positionner]]** ou non une valeur (% style="color: rgb(255,102,0);" %)**NULL**(%%) dans la colonne avant de l'écriture | ||
| 21 | * **[[Comparer>>doc:||anchor=comparer]]** la valeur d'une colonne à (% style="color: rgb(255,102,0);" %)**NULL**(%%) dans la condition d'un ordre SQL. | ||
| 22 | |||
| 23 | {{id ="decrire" name="decrire"/}}Décrire les données | ||
| 24 | Exemples de saisie de la contrainte SQL : | ||
| 25 | * Niveau conceptuel : [[image:Indicateur_NULL_MCD.jpg||data-xwiki-image-style-alignment="center"]] | ||
| 26 | |||
| 27 | * Niveau logique : [[image:Indicateur_NULL_MLD.jpg||data-xwiki-image-style-alignment="center"]] | ||
| 28 | |||
| 29 | {{id ="verifier" name="verifier"/}}Vérifier la valeur de la colonne | ||
| 30 | Pour cela, on dispose de la fonction prédéfinie (% style="color: rgb(255,102,0);" %)**&RECUPERER_INDIC**(%%) qui s'utilise comme suit : | ||
| 31 | |||
| 32 | |||
| 33 | {{code language="none"}} | ||
| 34 | W_NUM_CLIENT = 123 | ||
| 35 | Lire_Sql Client *Cond(CL_NUM_CLIENT = :W_NUM_CLIENT) | ||
| 36 | Si *SqlCode = *Normal | ||
| 37 | |||
| 38 | /* ___ La colonne nom du client peut contenir une valeur nulle. | ||
| 39 | /* ___ Pour le vérifier, utiliser la fonction avec comme paramètres : | ||
| 40 | /* ___ - le nom de l'entité Adelia | ||
| 41 | /* ___ - le nom de la propriété logique | ||
| 42 | |||
| 43 | Si &RECUPERER_INDIC(CLIENT;CL_NOM_CLIENT) = 0 | ||
| 44 | |||
| 45 | /* ___ La colonne CL_NOM_CLIENT n'a pas la valeur NULL | ||
| 46 | Lire_Sql PRESIDENT *Cond(PR_NOM = :CL_NOM_CLIENT) | ||
| 47 | ... | ||
| 48 | Sinon | ||
| 49 | /* ___ La colonne contient une valeur NULL | ||
| 50 | ... | ||
| 51 | Fin | ||
| 52 | Sinon | ||
| 53 | ... | ||
| 54 | Fin | ||
| 55 | |||
| 56 | {{/code}} | ||
| 57 | |||
| 58 | {{id ="positionner" name="positionner"/}}Positionner une valeur NULL dans une colonne | ||
| 59 | Afin de définir si la valeur d'une colonne contient NULL ou pas, il faut commencer par utiliser l'ordre L4G (% style="color: rgb(255,102,0);" %)**AFFECTER_INDIC**(%%). | ||
| 60 | Lorsque le premier paramètre contient (% style="color: rgb(255,102,0);" %)***VRAI**(%%), la valeur qui sera attribuée à la propriété sera positionnée à (% style="color: rgb(255,102,0);" %)**NULL**(%%) lors de l'écriture (création ou mise à jour). Dans le cas contraire, elle conservera la valeur contenue dans la variable. | ||
| 61 | Dans l'utilisation des ordres SQL de création ou de mise à jour, il est obligatoire d'utiliser le mot réservé (% style="color: rgb(255,102,0);" %)***INDIC_NULL**(%%) en paramètre. | ||
| 62 | Le fait d'utiliser une valeur nulle dépend uniquement de ce qui doit être mise en oeuvre au niveau du métier et permet d'indiquer que la donnée n'est pas renseignée. | ||
| 63 | |||
| 64 | {{hardis-info type="note" icon="true"}} | ||
| 65 | Pour une simplification du mode de gestion, vous pourriez mettre en place des règles de gestion qui simplifieraient la gestion des valeurs (% style="color: rgb(255,102,0);" %)**NULL**(%%) en utilisant systématiquement une zone de donnée en relation avec les colonnes. | ||
| 66 | {{/hardis-info}} | ||
| 67 | |||
| 68 | Ci après, deux exemples de mise en oeuvre : | ||
| 69 | ((( | ||
| 70 | ==== Exemple 1, sans règle de gestion ==== | ||
| 71 | ))) | ||
| 72 | |||
| 73 | |||
| 74 | {{code language="none"}} | ||
| 75 | Si W_NBR_ENFANT = 0 | ||
| 76 | Affecter_Indic *Vrai CLIENT CL_NOM_CLIENT | ||
| 77 | Sinon | ||
| 78 | Affecter_Indic *Faux CLIENT CL_NOM_CLIENT | ||
| 79 | Fin | ||
| 80 | ... | ||
| 81 | Creer_Sql CLIENT *Indic_Null | ||
| 82 | |||
| 83 | {{/code}} | ||
| 84 | |||
| 85 | ((( | ||
| 86 | ==== Exemple 2, avec une règle de gestion (génération avec RG implicite) ==== | ||
| 87 | ))) | ||
| 88 | |||
| 89 | (% style="color: rgb(51,51,51);" %)Il faut créer deux(%%) (% style="color: rgb(255,102,0);" %)**règles de gestion**(%%) (% style="color: rgb(51,51,51);" %):(%%) | ||
| 90 | * une RG de classe (% style="color: rgb(255,102,0);" %)**Création**(%%) | ||
| 91 | * une RG de classe (% style="color: rgb(255,102,0);" %)**Mise à jour**(%%). | ||
| 92 | |||
| 93 | |||
| 94 | Contenu de la règle de gestion implicite : | ||
| 95 | |||
| 96 | |||
| 97 | {{code language="none"}} | ||
| 98 | Decl BOOL W_BOO_CL_NOM_CLIENT /* --- zone de donnée pour la propriété CL_NOM_CLIENT | ||
| 99 | Affecter_Indic W_BOO_CL_NOM_CLIENT CLIENT CL_NOM_CLIENT | ||
| 100 | |||
| 101 | {{/code}} | ||
| 102 | |||
| 103 | |||
| 104 | Traitement dans le programme : | ||
| 105 | |||
| 106 | |||
| 107 | {{code language="none"}} | ||
| 108 | W_BOO_CL_NOM_CLIENT = (W_NBR_ENFANT = 0) | ||
| 109 | ... | ||
| 110 | Creer_Sql CLIENT *Indic_Null | ||
| 111 | |||
| 112 | {{/code}} | ||
| 113 | |||
| 114 | {{id ="comparer" name="comparer"/}}Comparer à NULL la valeur d'une colonne dans une requête SQL | ||
| 115 | Afin de tester si une colonne vaut (% style="color: rgb(255,102,0);" %)**NULL**(%%) dans une requête Sql, on utilisera la (% style="color: rgb(255,102,0);" %)**fonction scalaire**(%%) SQL (% style="color: rgb(255,102,0);" %)**EST_INDIC_NULL**(%%) directement dans la clause conditionnelle : | ||
| 116 | |||
| 117 | |||
| 118 | {{code language="none"}} | ||
| 119 | W_NUM_CLIENT = 123 | ||
| 120 | Lire_Sql CLIENT *Cond( EST_INDIC_NULL(CL_NOM_CLIENT) Et CL_NUM_CLIENT = :W_NUM_CLIENT) ) | ||
| 121 | Si *SqlCode = *Normal | ||
| 122 | /* ___ Le client existe et le nom n'est pas renseigné ___ | ||
| 123 | ... | ||
| 124 | Fin | ||
| 125 | |||
| 126 | {{/code}} | ||
| 127 | |||
| 128 | {{id ="casparticulier" name="casparticulier"/}}Cas particulier des fonctions sur les colonnes | ||
| 129 | Certaines fonctions telles que MAX ou bien MIN peuvent retourner une valeur (% style="color: rgb(255,102,0);" %)**NULL**(%%) alors que la colonne elle-même n'en gère pas. | ||
| 130 | Ce cas se produit à partir du moment où la sélection ne retourne pas d'enregistrement. | ||
| 131 | |||
| 132 | Pour éviter une erreur SQL (et un éventuel enregistrement dans la log du travail iSeries), nous recommandons d'utiliser une (% style="color: rgb(255,102,0);" %)**variable indicatrice**(%%) dans l'ordre SQL. | ||
| 133 | ((( | ||
| 134 | ==== Par exemple : ==== | ||
| 135 | ))) | ||
| 136 | |||
| 137 | |||
| 138 | {{code language="none"}} | ||
| 139 | Lire_Sql *Col(MAX(CL_MNT_CREDIT) :W_MNT_CREDIT_MAX) *Cond(CL_CAT_CLIENT = 'A') | ||
| 140 | |||
| 141 | {{/code}} | ||
| 142 | |||
| 143 | |||
| 144 | Dans le cas où il n'y a pas de catégorie de client égal à 'A' alors une erreur SQL est renvoyée. | ||
| 145 | ((( | ||
| 146 | ==== Pour éviter cela, il faut écrire : ==== | ||
| 147 | ))) | ||
| 148 | |||
| 149 | Dans le paragraphe de (% style="color: rgb(255,102,0);" %)**déclaration**(%%) | ||
| 150 | |||
| 151 | |||
| 152 | {{code language="none"}} | ||
| 153 | Ref(CL_MNT_CREDIT) W_MNT_CREDIT_MAX | ||
| 154 | Num_Bin_2 W_IND_MAX | ||
| 155 | |||
| 156 | {{/code}} | ||
| 157 | |||
| 158 | |||
| 159 | Dans un paragraphe de (% style="color: rgb(255,102,0);" %)**traitement**(%%) | ||
| 160 | |||
| 161 | |||
| 162 | {{code language="none"}} | ||
| 163 | Lire_Sql *Col(MAX(CL_MNT_CREDIT) :W_MNT_CREDIT_MAX W_IND_MAX) *Cond(CL_CAT_CLIENT = 'A') | ||
| 164 | Si W_IND_MAX < 0 | ||
| 165 | /* ___ La valeur renvoyée vaut NULL ___ | ||
| 166 | Sinon | ||
| 167 | /* ___ La valeur de W_MNT_CREDIT_MAX est renseignée avec la valeur max des enregistrements liés à la condition ___ | ||
| 168 | Fin | ||
| 169 | |||
| 170 | {{/code}} | ||
| 171 |