La banque décide de fêter la nouvelle année en partageant ses gains avec les anciens clients. Pour cela, elle ajoutera une somme sur tous les comptes des clients ayant effectués des opérations antérieures au 31/10/2018 et dont le montant du dépôt était supérieur à 2000 euros (valeur constante).
La directrice Elise vous demande d’écrire et de lancer une procédure stockée nommée proc_cadeaux permettant d’ajouter 19 euros (pour chaque opération trouvée)pour tous les comptes concernés et d’effectuer automatiquement la modification sur le solde du compte des clients. Il faut prévoir de réutiliser cette procédure l’an prochain et considérer que le montant du cadeau et la date peuvent changer !
Ci-dessous, la procédure ne modifie qu’une fois le solde dès qu’une opération est trouvée :
La requête UPDATE passera une fois sur chaque enregsitrement de la table compte ce qui est logique.
DELIMITER $$ CREATE DEFINER=`test`@`%` PROCEDURE `proc_cadeaux`(IN `cadeau` FLOAT UNSIGNED, IN `jour` DATE) COMMENT 'Procédure cadeau tp banque' BEGIN UPDATE compte SET compte.SOLDE=compte.SOLDE+cadeau WHERE NUMERO IN ( SELECT operations.NUMEROCOMPTE FROM operations WHERE operations.DATE < jour AND operations.TYPE = '+' AND operations.MONTANT > 2000 ); SELECT compte.NUMERO, compte.SOLDE FROM compte; END$$ DELIMITER ;
Ci-dessous, en ajoutant RIGHT OUTER JOIN et la même requête imbriquée, ça répond à notre demande :
Il faut savoir combien d’opérations remplissent les conditions par compte et modifier le solde avec le montant du cadeau multiplié par le nombre d’opérations.
DELIMITER $$ CREATE DEFINER=`test`@`%` PROCEDURE `proc_cadeaux`(IN `cadeau` FLOAT, IN `jour` DATE) MODIFIES SQL DATA BEGIN UPDATE compte RIGHT OUTER JOIN operations ON compte.NUMERO = operations.NUMEROCOMPTE SET compte.SOLDE = compte.SOLDE + cadeau * (SELECT COUNT(*) FROM operations WHERE compte.NUMERO = operations.NUMEROCOMPTE AND operations.DATE < jour AND operations.TYPE = '+' AND operations.MONTANT > 2000); SELECT compte.NUMERO, compte.SOLDE FROM compte; END$$ DELIMITER ;
Pour lancer l’exécution d’une procédure stockée, il faut utiliser la classe StoredProcedureQuery de la manière suivante :
StoredProcedureQuery maProcedure = entityManager.createStoredProcedureQuery(“proc_cadeaux”);
@Autowired private EntityManager entityManager; public void lancerProcedureCadeau(String jour, Float cadeau) { StoredProcedureQuery storedProcedure = entityManager.createStoredProcedureQuery("proc_cadeaux"); storedProcedure.registerStoredProcedureParameter(1, Float.class , ParameterMode.IN); storedProcedure.registerStoredProcedureParameter(2, Date.class, ParameterMode.IN); storedProcedure.setParameter(1, cadeau); Calendar date = Calendar.getInstance(); date.set(Integer.parseInt(jour.substring(0,4)), Integer.parseInt(jour.substring(5,7)), Integer.parseInt(jour.substring(8, 10))); storedProcedure.setParameter(2, date, TemporalType.DATE); storedProcedure.execute(); }
SET @cadeau='19'; SET @date='2018-10-31'; CALL `proc_cadeau`(@cadeau, @date);
Créer une table identique à celle de compte que vous nommerez compteriche. Vous pouvez ne pas activer les clefs étrangères codetypecompte et codetitulaire pour cette table.
CREATE TABLE IF NOT EXISTS `compteriche` ( `NUMERO` int(11) NOT NULL, `CODETYPECOMPTE` char(1) NOT NULL, `CODETITULAIRE` int(4) NOT NULL, `SOLDE` float(10,2) NOT NULL, PRIMARY KEY (`NUMERO`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
La directrice vous demande d’écrire un Trigger qui permet lors de chaque ouverture de compte courant dont la somme est supérieure à 10000 euros :
CREATE TRIGGER `compte_dupli_auto` AFTER INSERT ON `compte` FOR EACH ROW BEGIN IF NEW.solde >10000 AND NEW.codetypecompte='C' THEN INSERT INTO operations (`NUMEROCOMPTE`, `DATE`, `LIBELLE`, `MONTANT`, `TYPE`) VALUES (NEW.numero, '2019-01-08', 'ouverture', NEW.solde, '+'); INSERT INTO `compteriche` (`NUMERO`, `CODETYPECOMPTE`, `CODETITULAIRE`, `SOLDE`) VALUES (NEW.numero, NEW.codetypecompte, NEW.codetitulaire, NEW.solde); END IF; END
On vous demande de mettre en place un trigger qui permet après chaque mise à jour des informations d’un Titulaire, de conserver les anciennes données dans la table en y ajoutant la date du jour de la modification et le type d’action. Ici, l’action sera égale à “MAJ” pour mise à jour.
Voici le script de la Table :
CREATE TABLE `histotitulaire` ( `ID` int NOT NULL AUTO_INCREMENT, `DATEACTION` datetime NOT NULL, `ACTION` varchar(15) DEFAULT NULL, `CODE` int(4) NOT NULL, `PRENOM` varchar(32) NOT NULL, `NOM` varchar(32) NOT NULL, `ADRESSE` varchar(32) DEFAULT NULL, `CODEPOSTAL` char(5) DEFAULT NULL, PRIMARY KEY (`ID`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
FOR EACH ROW BEGIN INSERT INTO histotitulaire (DATEACTION, ACTION, CODE, PRENOM, NOM,ADRESSE,CODEPOSTAL) VALUES(now(),'MAJ',OLD.CODE,OLD.PRENOM,OLD.NOM,OLD.ADRESSE,OLD.CODEPOSTAL); END
Code MySQL récupéré pour ce trigger :
CREATE TRIGGER `titulaire_update` BEFORE UPDATE ON `titulaire` FOR EACH ROW BEGIN INSERT INTO histotitulaire (DATEACTION, ACTION, CODE, PRENOM, NOM,ADRESSE,CODEPOSTAL) VALUES(now(),'MAJ',OLD.CODE,OLD.PRENOM,OLD.NOM,OLD.ADRESSE,OLD.CODEPOSTAL); END
Vous n’avez rien à faire en JAVA pour les Triggers puisque par définition ils se déclenchent en fonction d’un événément sur une table de votre base de données.
Lien vers le site MySQLtutorial.org
Auteur : Philippe Bouget