Aller au contenu
Réussir mon BTS SIO

Tape une notion, une commande ou le nom d'une épreuve.

Par exemple

Chapitre 1418 minIntermédiaire

Épreuve blanche E6 n° 2 : contrôler les licences

Par Josselyn C., prof de BTS SIO. Mis à jour le .

À la fin de ce chapitre, tu sauras

  • t'entraîner sur une deuxième épreuve E6 complète ;
  • traiter un ajustement de la commission ;
  • réussir la recette et l'entretien d'explicitation.

4 exercices corrigés

Cette deuxième épreuve blanche de l'E6 SLAM porte sur une application de bureau : la commission a choisi GestParc, le client lourd C# relié à MySQL, plutôt que l'application web. Prépare-toi à ce cas : on pratique souvent moins sa réalisation de 1re année. Le sujet mobilise surtout la compétence « Gérer les données » : une règle placée dans la base, une vue, et leur intégration dans un formulaire WinForms. Même déroulé que l'épreuve blanche n° 1 : chronomètre, commission jouée par quelqu'un, réponses ouvertes après coup.

Ce que la commission connaît de ta réalisation

GestParc, application de bureau C# WinForms (.NET 10) pour le service informatique de Sorbier Logistique. Elle utilise la base parc décrite dans le cours SQL : postes, logiciels (avec nb_licences, vide pour un logiciel libre), installations (clé primaire id_poste, id_logiciel). L'accès aux données passe par des classes DAO et MySqlConnector, avec des requêtes paramétrées. Le formulaire FrmInstallation propose deux listes déroulantes, un poste et un logiciel, et un bouton « Installer ».

Ta base de test est la base parc du cours SQL, plus trois installations d'Acrobat Pro saisies avant l'évolution :

sql
INSERT INTO installation (id_poste, id_logiciel, date_installation) VALUES
  (1, 8, '2025-01-06'), (2, 8, '2025-01-06'), (3, 8, '2025-01-06');

Acrobat Pro (id_logiciel 8) a donc 2 licences pour 3 installations. Odoo (id_logiciel 5) : 8 licences, 7 installations, absent des postes 1, 2 et 9 à 14. Firefox (id_logiciel 3) : logiciel libre, absent du poste 14 seulement.

L'expression des besoins

Réalisation professionnelle retenue : n° 1, GestParc.

Circonstances de l'expression des besoins. Lors d'un audit des licences, le responsable informatique a constaté qu'Acrobat Pro était installé sur 3 postes pour 2 licences achetées. Un éditeur peut facturer les installations en trop. Les installations sont saisies dans GestParc, mais aussi importées chaque trimestre par un script SQL fourni par l'outil d'inventaire.

Spécifications fonctionnelles de la production attendue.

  1. L'ajout d'une installation est refusé quand toutes les licences du logiciel sont utilisées, quelle que soit la façon dont l'installation est ajoutée.
  2. Dans GestParc, le technicien voit un message clair, avec le logiciel, le nombre d'installations et le nombre de licences.
  3. Les logiciels libres, sans nombre de licences, ne sont pas limités.
  4. Un nouvel écran liste les logiciels en dépassement : nom, éditeur, licences, installations, écart.

Documents fournis. Le MLD de la base parc, une capture de FrmInstallation.

Production attendue. L'évolution de la base et de GestParc.

Documentation à présenter en appui de la solution. Documentation technique de la règle ; rapport de test.

Phase 1 : la préparation

Exercice 1 sur 4 Ta feuille de préparation (30 minutes) Réussi À revoir

Produis ta feuille : reformulation, quatre questions, grille des six axes avec au moins trois implicites et une ambiguïté, spécifications techniques, outils, alternative écartée, vital et confort.

Voir la réponseMasquer la réponse de l'exercice 1

Reformulation. « Une nouvelle installation doit être refusée par la base elle-même quand le logiciel n'a plus de licence libre ; GestParc affiche un message explicite ; un écran montre les dépassements existants. »

Les quatre questions.

QuestionRéponse
Quoi ?une règle de licences appliquée à tout ajout, un message dans GestParc, une liste des dépassements
Où ?la base (un trigger sur installation, une vue) ; FrmInstallation.cs pour le message ; un nouveau formulaire FrmDepassements et une méthode dans LogicielDao.cs
Quel impact ?les installations existantes ne sont pas touchées ; le script d'import peut désormais échouer sur une ligne ; InstallationDao.Ajouter ne change pas
Quelles compétences ?gérer les données (dominante : programmation dans le SGBD, requête de regroupement), maintenance évolutive

La grille des six axes.

AxeImplicite et décision
Canal« quelle que soit la façon » : le contrôle doit être dans la base, car le script d'import n'utilise pas GestParc
Déclencheurchaque INSERT dans installation
Acteursle technicien dans GestParc, le script d'import ; le responsable consulte les dépassements
Cas limiteslogiciel libre (nb_licences vide) : jamais limité ; Acrobat déjà en dépassement : on n'efface rien, mais toute nouvelle installation est refusée ; une désinstallation libère une licence sans rien coder, puisque le comptage est fait à chaque ajout ; deux techniciens qui prennent la dernière licence au même instant ; un logiciel déjà installé sur le poste, déjà refusé par la clé primaire
Donnéesle message doit contenir le nom, les installations et les licences ; la liste des dépassements se calcule, elle ne se stocke pas
Sécurité et conformitéle respect des licences est une obligation contractuelle envers l'éditeur : c'est le « contexte juridique » du besoin

Ambiguïté. « Le besoin ne dit pas ce que doit faire le script d'import quand une ligne est refusée. La base renverra une erreur sur cette ligne ; je pars du principe que le script s'arrête et que le technicien traite le cas à la main, puisqu'il faut décider d'acheter une licence ou de désinstaller. Si vous voulez que le script continue et liste les refus, il faut le modifier, ce qui sort de GestParc. »

Spécifications techniques.

  • Trigger BEFORE INSERT ON installation : lit nb_licences du logiciel ; s'il n'est pas vide, compte les installations ; si le compte atteint le nombre de licences, lève une erreur SIGNAL SQLSTATE '45000' avec le message demandé.
  • Verrou FOR UPDATE sur la ligne du logiciel, pour que deux ajouts simultanés passent l'un après l'autre.
  • Vue v_licences_depassees : jointure logiciel et installation, GROUP BY, HAVING COUNT(*) > nb_licences.
  • GestParc : dans FrmInstallation, intercepter la MySqlException dont le code d'erreur (ErrorCode) vaut 1644 (l'erreur levée par SIGNAL) et afficher son message ; un formulaire FrmDepassements avec un DataGridView alimenté par la vue.
  • Tests : script SQL de test sur une copie de la base, puis essais dans GestParc ; rapport de test.

Outils. Visual Studio et MySqlConnector, déjà utilisés ; le client MySQL pour écrire et tester le trigger avant de toucher au C#.

Alternative écartée. Un SELECT COUNT(*) dans GestParc avant l'INSERT. Il ne protège pas du script d'import, ce qui contredit la spécification 1, et deux techniciens simultanés passeraient tous les deux entre la lecture et l'écriture.

Vital et confort.

VitalConfort
trigger et message, testés dans le client MySQLmise en couleur de l'écart dans la grille
message dans FrmInstallationexport de la liste
vue des dépassementsmenu d'accès au nouvel écran
FrmDepassements minimal, documentation, rapport

Tu avais trouvé ?

Phase 1 : l'entretien

Exercice 2 sur 4 Les questions de la commission Réussi À revoir

Réponds en deux à quatre phrases.

  1. « Pourquoi un trigger plutôt qu'une procédure stockée appelée par GestParc ? »
  2. « Que se passe-t-il pour Acrobat Pro, déjà en dépassement ? »
  3. « Comment le message du trigger arrive-t-il jusqu'au technicien ? »
  4. « Et si on diminue le nombre de licences d'un logiciel en dessous du nombre d'installations ? »
Voir la réponseMasquer la réponse de l'exercice 2
  1. « Une procédure ne protège que ceux qui l'appellent : le script d'import fait des INSERT directs. Le trigger s'exécute à chaque INSERT, d'où qu'il vienne. C'est la seule façon de respecter "quelle que soit la façon dont l'installation est ajoutée". »
  2. « Le trigger ne regarde que les nouveaux ajouts : les trois installations existantes restent. Toute nouvelle installation d'Acrobat est refusée, puisque 3 est déjà au-delà de 2. Le dépassement apparaît dans le nouvel écran ; le responsable décidera d'acheter une licence ou de désinstaller, ce n'est pas au code de choisir. »
  3. « SIGNAL SQLSTATE '45000' lève une erreur MySQL de numéro 1644, avec mon texte comme message. MySqlConnector la transforme en MySqlException ; je l'intercepte par son code d'erreur dans FrmInstallation et j'affiche son message dans une boîte de dialogue. »
  4. « Rien ne l'empêche aujourd'hui : la modification est acceptée et le logiciel apparaît dans la liste des dépassements. Je pourrais ajouter un trigger sur logiciel qui refuse la baisse, mais c'est parfois une décision volontaire, par exemple une licence résiliée. Je préfère le rendre visible plutôt que de l'interdire, et je vous propose de le noter comme évolution. »

Tu avais trouvé ?

L'ajustement de la commission

Lis-le après l'entretien. Au verso :

« L'écran des dépassements peut être remplacé par la vue, consultée dans le client MySQL. En revanche, la règle doit aussi s'appliquer quand une installation existante est modifiée pour passer sur un autre logiciel. »

Un ajustement qui retire et qui ajoute : le formulaire FrmDepassements passe en confort, et un second déclencheur apparaît, sur UPDATE. Pour ne pas écrire la règle deux fois, place-la dans une procédure appelée par les deux triggers.

Phase 2 : la réalisation

Exercice 3 sur 4 Réalise la solution ajustée (1 heure) Réussi À revoir

Livre la procédure et les triggers, la vue, la modification de FrmInstallation, le script de test et son résultat, la documentation technique, le rapport de test.

Voir la réponseMasquer la réponse de l'exercice 3

La règle dans la base.

sql
-- migrations/2027-04-licences.sql
DELIMITER //

CREATE PROCEDURE verifier_licence(IN p_id_logiciel INT)
BEGIN
  DECLARE v_nom VARCHAR(60);
  DECLARE v_licences INT;
  DECLARE v_installees INT;
  DECLARE v_message VARCHAR(128);

  -- Verrou sur la ligne du logiciel : deux ajouts simultanés passent l'un après l'autre.
  SELECT nom, nb_licences INTO v_nom, v_licences
    FROM logiciel WHERE id_logiciel = p_id_logiciel FOR UPDATE;

  IF v_licences IS NOT NULL THEN
    SELECT COUNT(*) INTO v_installees FROM installation WHERE id_logiciel = p_id_logiciel;
    IF v_installees >= v_licences THEN
      SET v_message = CONCAT(v_nom, ' : ', v_installees, ' installation(s) pour ', v_licences, ' licence(s)');
      SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = v_message;
    END IF;
  END IF;
END //

CREATE TRIGGER trg_installation_avant_ajout
BEFORE INSERT ON installation
FOR EACH ROW
BEGIN
  CALL verifier_licence(NEW.id_logiciel);
END //

CREATE TRIGGER trg_installation_avant_modif
BEFORE UPDATE ON installation
FOR EACH ROW
BEGIN
  IF NEW.id_logiciel <> OLD.id_logiciel THEN
    CALL verifier_licence(NEW.id_logiciel);
  END IF;
END //

DELIMITER ;

CREATE OR REPLACE VIEW v_licences_depassees AS
SELECT l.id_logiciel, l.nom, l.editeur, l.nb_licences,
       COUNT(*) AS nb_installations,
       COUNT(*) - l.nb_licences AS ecart
  FROM logiciel l
  JOIN installation i ON i.id_logiciel = l.id_logiciel
 WHERE l.nb_licences IS NOT NULL
 GROUP BY l.id_logiciel, l.nom, l.editeur, l.nb_licences
HAVING COUNT(*) > l.nb_licences;

-- Annulation :
-- DROP TRIGGER trg_installation_avant_ajout; DROP TRIGGER trg_installation_avant_modif;
-- DROP PROCEDURE verifier_licence; DROP VIEW v_licences_depassees;

Le trigger BEFORE UPDATE ne vérifie que les changements de logiciel : modifier la date d'installation ne doit pas être refusé parce que le logiciel est plein. Le cours Procédures stockées et triggers détaille cette syntaxe.

Le formulaire.

csharp
// FrmInstallation.cs
private void btnInstaller_Click(object sender, EventArgs e)
{
    if (cboPoste.SelectedValue is not int idPoste || cboLogiciel.SelectedValue is not int idLogiciel)
    {
        MessageBox.Show("Choisis un poste et un logiciel.", "Installation",
            MessageBoxButtons.OK, MessageBoxIcon.Warning);
        return;
    }
    try
    {
        _installationDao.Ajouter(idPoste, idLogiciel, DateTime.Today);
        ChargerInstallations();
    }
    catch (MySqlException ex) when (ex.Number == 1644)   // erreur levée par SIGNAL dans la base
    {
        MessageBox.Show($"Installation refusée. {ex.Message}", "Plus de licence disponible",
            MessageBoxButtons.OK, MessageBoxIcon.Warning);
    }
    catch (MySqlException ex) when (ex.Number == 1062)   // clé primaire : déjà installé sur ce poste
    {
        MessageBox.Show("Ce logiciel est déjà installé sur ce poste.", "Installation",
            MessageBoxButtons.OK, MessageBoxIcon.Information);
    }
}

InstallationDao.Ajouter ne change pas : c'est toujours un INSERT paramétré. Toute la règle vit dans la base.

Le script de test, lancé sur une copie de la base :

sql
INSERT INTO installation (id_poste, id_logiciel, date_installation)
  VALUES (14, 5, CURDATE());                         -- Odoo, 8e installation : acceptée
INSERT INTO installation (id_poste, id_logiciel, date_installation)
  VALUES (9, 5, CURDATE());                          -- Odoo, 9e : refusée
INSERT INTO installation (id_poste, id_logiciel, date_installation)
  VALUES (14, 3, CURDATE());                         -- Firefox, libre : acceptée
INSERT INTO installation (id_poste, id_logiciel, date_installation)
  VALUES (14, 8, CURDATE());                         -- Acrobat Pro, déjà en dépassement : refusée
UPDATE installation SET date_installation = CURDATE()
 WHERE id_poste = 14 AND id_logiciel = 5;            -- même logiciel : acceptée
UPDATE installation SET id_logiciel = 5
 WHERE id_poste = 9 AND id_logiciel = 3;             -- Firefox remplacé par Odoo, plein : refusée
SELECT nom, nb_licences, nb_installations, ecart FROM v_licences_depassees;
text
ERROR 1644 (45000): Odoo : 8 installation(s) pour 8 licence(s)
ERROR 1644 (45000): Acrobat Pro : 3 installation(s) pour 2 licence(s)
ERROR 1644 (45000): Odoo : 8 installation(s) pour 8 licence(s)

+-------------+-------------+------------------+-------+
| nom         | nb_licences | nb_installations | ecart |
+-------------+-------------+------------------+-------+
| Acrobat Pro |           2 |                3 |     1 |
+-------------+-------------+------------------+-------+

La documentation technique, une demi-page : la règle (« une installation est refusée quand le nombre d'installations du logiciel atteint nb_licences ; les logiciels sans nb_licences ne sont pas limités »), les objets créés (procédure, deux triggers, vue) et leur script d'annulation, le code d'erreur 1644 et son message, l'effet sur le script d'import (il s'arrête sur la ligne refusée), la requête de consultation des dépassements.

Le rapport de test.

N°CasAttenduObtenuConforme
1dernière licence d'Odooacceptéeacceptéeoui
2Odoo au-delà des licencesrefus, message avec 8 et 8conformeoui
3logiciel libreacceptéeacceptéeoui
4Acrobat Pro, déjà en dépassementrefusconformeoui
5modification de la date seuleacceptéeacceptéeoui
6changement vers un logiciel pleinrefusconformeoui
7vue des dépassementsAcrobat Pro, écart 1conformeoui
8GestParc, Odoo sur le poste 9boîte « Plus de licence disponible »conformeoui
9GestParc, logiciel déjà installémessage de doublonconformeoui

Le formulaire FrmDepassements, passé en confort par l'ajustement, n'est pas fait.

Tu avais trouvé ?

La recette et l'entretien d'explicitation

Exercice 4 sur 4 Les questions de la recette Réussi À revoir

  1. « Pourquoi une procédure, si chaque trigger pouvait contenir la règle ? »
  2. « À quoi sert le FOR UPDATE dans la procédure ? »
  3. « Pourquoi la vue a-t-elle un HAVING et pas un WHERE ? »
  4. « Le message dit "8 installation(s) pour 8 licence(s)". Un technicien comprend-il pourquoi c'est refusé ? »
Voir la réponseMasquer la réponse de l'exercice 4
  1. « Pour écrire la règle une seule fois. Si l'éditeur change sa façon de compter, par exemple une licence pour deux postes, je modifie la procédure et les deux triggers suivent. Deux copies finiraient par diverger. »
  2. « Deux techniciens qui ajoutent la dernière licence au même instant liraient tous les deux sept installations et passeraient tous les deux. Le verrou sur la ligne du logiciel fait attendre le second jusqu'à la fin de la transaction du premier : il compte alors huit et il est refusé. »
  3. « WHERE filtre les lignes avant le regroupement : il ne connaît pas encore le nombre d'installations. HAVING filtre les groupes, après le COUNT. Le WHERE nb_licences IS NOT NULL reste en WHERE, parce qu'il porte sur une colonne de ligne. »
  4. « Il comprend que tout est pris, mais le message pourrait être plus clair. J'écrirais "Plus de licence disponible pour Odoo : 8 installations pour 8 licences", et j'adapterais le singulier et le pluriel. C'est une amélioration de dix minutes, que j'ajoute à mes notes. »

Tu avais trouvé ?

Chapitre terminé !

Fais les 4 exercices avant de passer à la suite : c'est en t'entraînant que tout se fixe.

chapitres
–
de série
–
du cours
–
Cours suivant : E6 SISRRevoir le sommaire du cours