Affichage des articles dont le libellé est Piège. Afficher tous les articles
Affichage des articles dont le libellé est Piège. Afficher tous les articles

mardi 10 décembre 2013

Le piège de la mise à jour cachée

Pignouf Anatole (matricule 1007) a obtenu au sein de l'entreprise une belle promotion: il passe du service "Relations publiques" au service "Recherche" avec à la clef une augmentation de salaire dont le calcul s'effectuera dorénavant sur base de l'échelle 11r.
Il s'occupera du projet "Lave-linge à pédales", projet porteur puisque synonyme d'économie d'énergie.
Reste à mettre à jour les données informatique via un formulaire libreoffice connecté à la base de données PostgreSQL utilisée par l'entreprise:


Dans la table qui sera mise à jour, "Service" et "Projet" apparaissent sous forme de code, mais l'utilisation de listes déroulantes fait que ces codes sont transparents pour l'utilisateur.
Ce qui est affiché à l'écran sous forme d'un seul formulaire est en fait composé d'un formulaire maître "Sélection" et de deux sous-formulaires: "Employés" et "Gestion".


La table "sélection" source de données de "Sélection" contient un matricule qui est sans arrêt mis à jour et qui sert à appeler le dossier désiré. La façon dont tout cela fonctionne est expliqué ici.
Après avoir procédé, la personne chargée d'actualiser les données informatiques en ce qui concerne "Service" et "Projet", clique sur la petite disquette (qui a pris des couleurs) de la barre d'outils:


  ce qui donne:


Il constate alors que depuis un autre poste de travail les données "Ancienneté" et "Échelle de traitement" ont été modifiées (ce qui montre d'ailleurs que chaque enregistrement s'accompagne d'une relecture des données).
Parfait: de toute façon ce n'était pas son job de le faire!
Supposons maintenant que au lieu de cliquer sur l'icône "disquette", l'encodeur appuie sur "Enter" autant de fois qu'il le faut (3 fois) pour amener le focus sur la zone de saisie "matricule". Dès l'instant où le focus quitte le sous-formulaire "Gestion", les données s'enregistrent et nous arrivons à ceci:


L'ancienneté affichée est bien 9, par contre en ce qui concerne l'échelle de traitement on a 12.
Et voilà, le piège s'est refermé! Le piège de la mise à jour cachée!
L'échelle de traitement a été dans un premier temps portée à la valeur '11r' depuis un autre poste, mais ensuite  elle est revenue à la valeur '12'.
Mais pour notre encodeur l'échelle de traitement a toujours été à '12' et il n'a touché à rien. il s'agit donc bien d'un piège et d'une mise à jour cachée.
D'autre part, la personne qui a porté l'échelle de traitement à la valeur '11r' croit avoir fait son travail et elle n'y reviendra plus.
Pour éviter le piège, on peut choisir "Tabulation = non" au niveau des propriétés du contrôle:


ce qui n'empêchera pas que l'on puisse mettre à jour la donnée, à moins de choisir "En lecture seule = OUI".

NB: le piège a été testé avec une grandeur de type character ce qui est le cas de l'échelle de traitement.

dimanche 27 octobre 2013

Le piège du chemin absolu

Dans la série 'Le piège', voici 'Le piège du chemin absolu' (le premier épisode  de la série se trouve ici).
Au départ nous avons installé une distribution (disons Manjaro) avec une partition séparée pour les dossiers personnels (montée en /home) et un utilisateur appelé toto.
Ensuite, à côté de cette distribution, nous en avons installé une autre (disons Xubuntu) utilisant la même partition séparée pour les données. Nous avons appelé l'utilisateur totox et non pas toto afin d'avoir un autre dossier personnel, ceci pour éviter les conflits entre fichiers de configuration de versions différentes. Cependant nous voulons dans Xubuntu travailler avec les mêmes données que dans Manjaro. Comme totox dans Xubuntu a le même id (1000) que toto dans Manjaro, aucun problème de droits ne pourra s'y opposer. Donc travaillant dans Xubuntu où nous sommes totox, nous supprimons le répertoire Documents de notre dossier personnel (/home/totox) et effectuons un glisser-déposer du répertoire Documents de /home/toto vers /home/totox


et dans le menu contextuel qui surgit, nous sélectionnons 'Lier ici':


Voilà c'est fait:


Lorsque nous cliquons sur le lien 'Documents', nous accédons directement aux documents de toto:



Comme nous sommes insatiable, nous installons encore une autre distribution (par exemple Fedora) avec cette fois-ci une partition pour les données qui n'est pas celle utilisée pour Manjaro et Xubuntu.
Rien ne nous empêche donc d'appeler notre utilisateur toto.
Et finalement nous installons Kubuntu: utilisateur totok et même partition montée dans /home que Fedora.
Tout est en place pour que le piège fonctionne!
Dans Kubuntu, nous voulons accéder au dossier personnel de totox (utilisateur de Xubuntu).
Nous devons pour ce faire monter la partition contenant ce dossier. Afin de la retrouver plus facilement, nous avons donné à cette partition (commande e2label) le label home-b.
Pour la monter il suffit de cliquer sur ce qui convient dans la barre latérale du navigateur de fichiers:


La partition est alors montée dans /media/home-b:


nous cliquons sur 'Documents' et nous tombons dans le piège! Les données ne sont pas celles attendues:


Essayons de comprendre ce qu'il en est en ouvrant un (émulateur de) terminal au niveau du dossier 'totox' et en y lançant la commande 'ls -l':


Nous constatons que le chemin contenu dans le lien 'Documents' est un chemin absolu: il part toujours de la racine du système quel que soit l'endroit où se trouve le lien. En fait les données que nous avons affichées sont les données du toto de Fedora (et non celles du toto de Manjaro).
il faudrait remplacer ce chemin absolu par un chemin relatif. Pour cela il suffit d'exécuter la commande

ln -sf ../toto/Documents .

(Le point final fait partie de la commande: il symbolise le répertoire courant)


Le chemin part maintenant du répertoire parent du dossier totox (donc de /media/home-b) et il aboutit au bon endroit:




Si nous sommes dans Xubuntu, le répertoire parent, départ du chemin, est maintenant /home et de nouveau nous atterrissons là où nous voulons aller.

lundi 3 juin 2013

Le piège du null

Plantons le décor:
Une table "dépenses" créée avec l'instruction:
CREATE TABLE dépenses
(référence CHAR(9) PRIMARY KEY,
 date_exec DATE,
 montant NUMERIC(13,2),
 détails VARCHAR(50),
 code_u CHAR(2))
;
et dans laquelle quelques données ont été placées.

un code_u dont la signification est:

 code_u | signification     
--------+----------------
 01     | Médecin
 02     | Grande surface
 03     | Carburant
 04     | Restaurant

Voilà, le décor est planté.

Examinons le contenu de la table "dépenses", par exemple depuis un terminal psql si nous travaillons avec PostgreSQL:


Nous désirons mettre à jour code_u avec cette instruction:
UPDATE dépenses
SET code_u = '02'
WHERE (détails = 'Courrefar'
OR détails = 'Caro'
OR détails = 'Aupré'
)
AND code_u <> '02'
;
La ligne AND est là pour éviter les mises à jour inutiles (mise à jour des rangées avec code_u valant déjà '02').
En principe 3 rangées devraient être impactées: celles dont la référence se termine par 17, 21 et 22.
Vérifions s'il en sera bien ainsi:


Il manque la rangée 2013-0022. Pourtant rien ne semble la distinguer (par rapport aux critères de sélection) de la rangée 2013-0021.
Poussons plus loin  les investigations.
L'utilisation de la méta-commande \pset null nous permet de choisir ce qui sera imprimé dans le cas de la valeur NULL. Par défaut rien n'est imprimé


Nous voyons maintenant apparaître une différence essentielle entre les rangées 2013-0021 et 2013-0022. Pour la rangée 2013-0021, code_u est caractérisé par une chaîne de caractère vide, ce qui permet de dire que code_u n'est pas égal à 01, ni à 02, 03, 04.(ou sinon la chaîne ne serait pas vide).
Par contre dans le cas de la rangée 2013-0022, l'indication NULL signifie que la base de données ne contient aucune information concernant code_u. Pour cette rangée, code_u est inconnu: il peut très bien valoir '02', où pas. Il est donc impossible de mettre cette rangée dans l'ensemble de celles dont le code_u vaut '02' ou dans l'ensemble de celles dont le code_u est différent de '02'. L'union des 2 ensembles nous fournit 7 rangées (au lieu de 9):


Si le critère de sélection est code_u = '02', les rangées avec code_u NULL se sont pas reprises. Mais elles ne le sont pas non plus si le critère de sélection est code_u différent de '02'.
Et voilà le piège, le piège du NULL dans lequel il ne faut pas tomber! Y tomber, c'est être nul!
L'instruction à utiliser pour la mise à jour devrait être:
UPDATE dépenses
SET code_u = '02'
WHERE (détails = 'Courrefar'
OR détails = 'Caro'
OR détails = 'Aupré'
)
AND (code_u <> '02'
OR code_u IS NULL
)
;

Dans le cas d'une base de données avancée comme PostgreSQL, qui gère l'intégrité référentielle, nous aurions pu après avoir créé une table destinée à contenir les significations de code_u:
CREATE TABLE utilisations
(code_u CHAR(2) PRIMARY KEY,
 signification VARCHAR(20))
;
créer la table "dépenses" comme suit:
CREATE TABLE dépenses
(référence CHAR(9) PRIMARY KEY,
 date_exec DATE,
 montant NUMERIC(13,2),
 détails VARCHAR(50),
 code_u CHAR(2) REFERENCES utilisations)
;
Dans ce cas les seules valeurs autorisées pour code_u auraient été celles qui figurent dans la table "utilisations". Une rangée comme la 2013-0021 n'aurait pas pu exister, mais bien des rangées avec code_u à la valeur NULL.
La notion d'intégrité référentielle a été étudiée dans ce billet.