Bon, bon, bon... J'en suis là...
J'ai renommé ma table horaire (Daphné ne m'en voudra pas, j'imagine)...
Quand ça tournera pour une personne, j'ajouterai un champ login et je réadapterai tout pour que ça tourne pour tout le monde qui voudra saisir ses horaires...
J'ai renommé le champ 'date' 'jour' parce que j'ai souvent la flemme d'échapper les mots réservés SQL.
Et j'ai posé des indexes de ouf... Je vous montre tout ça.
Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72 -- -- Base de données : `entrepot` -- -- -------------------------------------------------------- -- -- Structure de la table `horaire` -- DROP TABLE IF EXISTS `horaire`; CREATE TABLE IF NOT EXISTS `horaire` ( `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, `jour` date NOT NULL, `debut` time NOT NULL, `fin` time NOT NULL, PRIMARY KEY (`id`), KEY `jour_index` (`jour`), KEY `debut_index` (`debut`), KEY `fin_index` (`fin`), KEY `complet_index` (`jour`,`debut`,`fin`), KEY `jour_debut_index` (`jour`,`debut`), KEY `jour_fin_index` (`jour`,`fin`) ) ENGINE=InnoDB AUTO_INCREMENT=40 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPRESSED; -- -- Déchargement des données de la table `horaire` -- INSERT INTO `horaire` (`id`, `jour`, `debut`, `fin`) VALUES (35, '2018-01-01', '07:00:00', '11:30:00'), (36, '2018-01-15', '07:00:00', '11:00:00'), (37, '2018-03-15', '18:00:00', '24:00:00'), (38, '2018-03-16', '00:00:00', '04:00:00'), (39, '2018-05-05', '14:00:00', '16:00:00'), (1, '2018-05-14', '09:00:00', '21:00:00'), (2, '2018-05-15', '08:00:00', '10:00:00'), (3, '2018-05-16', '09:00:00', '18:00:00'), (4, '2018-05-17', '09:00:00', '18:00:00'), (5, '2018-05-18', '09:00:00', '18:00:00'), (6, '2018-05-19', '09:00:00', '18:00:00'), (7, '2018-05-20', '09:00:00', '18:00:00'), (8, '2018-05-21', '09:00:00', '18:00:00'), (9, '2018-05-22', '09:00:00', '18:00:00'), (10, '2018-05-23', '09:00:00', '18:00:00'), (11, '2018-05-24', '09:00:00', '18:00:00'), (12, '2018-05-25', '09:00:00', '18:00:00'), (13, '2018-05-26', '09:00:00', '18:00:00'), (14, '2018-05-27', '09:00:00', '18:00:00'), (15, '2018-05-28', '09:00:00', '18:00:00'), (16, '2018-05-29', '09:00:00', '18:00:00'), (17, '2018-05-30', '09:00:00', '18:00:00'), (18, '2018-05-31', '09:00:00', '18:00:00'), (19, '2018-06-01', '09:00:00', '18:00:00'), (20, '2018-06-02', '09:00:00', '18:00:00'), (21, '2018-06-03', '09:00:00', '18:00:00'), (22, '2018-06-04', '09:00:00', '18:00:00'), (23, '2018-06-05', '09:00:00', '18:00:00'), (24, '2018-06-06', '09:00:00', '18:00:00'), (25, '2018-06-07', '09:00:00', '18:00:00'), (26, '2018-06-08', '09:00:00', '18:00:00'), (27, '2018-06-09', '09:00:00', '18:00:00'), (28, '2018-06-10', '09:00:00', '18:00:00'), (29, '2018-06-11', '09:00:00', '18:00:00'), (30, '2018-06-12', '09:00:00', '18:00:00'), (31, '2018-06-13', '09:00:00', '18:00:00'), (32, '2018-06-14', '09:00:00', '18:00:00'), (33, '2018-06-15', '09:00:00', '18:00:00'), (34, '2018-06-16', '09:00:00', '18:00:00'); COMMIT;
Ensuite je bricole ces triggers de non chevauchement. (non, non, Jreaux, je ne fouette pas et je ne chevauche pas davantage, LOL)...
Ca bloque dès le début... if exists coince...
Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 CREATE TRIGGER no_overlapping_insert BEFORE INSERT ON horaire IF EXISTS ( SELECT * FROM horaire WHERE STR_TO_DATE(CONCAT(jour, ' ', debut), '%Y-%m-%d %H:%i:%s') <= NEW.STR_TO_DATE(CONCAT(jour, ' ', fin), '%Y-%m-%d %H:%i:%s') AND STR_TO_DATE(CONCAT(jour, ' ', fin), '%Y-%m-%d %H:%i:%s') >= NEW.STR_TO_DATE(CONCAT(jour, ' ', debut), '%Y-%m-%d %H:%i:%s') ) THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Insertion impossible car chevauchement de date !'; END IF; CREATE TRIGGER no_overlapping_update BEFORE UPDATE ON horaire IF EXISTS ( SELECT * FROM horaire WHERE STR_TO_DATE(CONCAT(jour, ' ', debut), '%Y-%m-%d %H:%i:%s') <= NEW.STR_TO_DATE(CONCAT(jour, ' ', fin), '%Y-%m-%d %H:%i:%s') AND STR_TO_DATE(CONCAT(jour, ' ', fin), '%Y-%m-%d %H:%i:%s') >= NEW.STR_TO_DATE(CONCAT(jour, ' ', debut), '%Y-%m-%d %H:%i:%s') ) THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Modification impossible car chevauchement de date !'; END IF;
Sur le fond, la requête de chevauchement fonctionne :
Si je recherche le 1er janvier de 08 à 12H, cela me retourne bien qu'en base, j'ai déjà le 1er janvier de 07H à 11H30...
Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 SELECT * FROM horaire WHERE STR_TO_DATE(CONCAT(jour, ' ', debut), '%Y-%m-%d %H:%i:%s') <= STR_TO_DATE('2018-01-01 12:00:00', '%Y-%m-%d %H:%i:%s') AND STR_TO_DATE(CONCAT(jour, ' ', fin), '%Y-%m-%d %H:%i:%s') >= STR_TO_DATE('2018-01-01 08:00:00', '%Y-%m-%d %H:%i:%s')
edit encore !!!
La requête précédente ne permettait pas les saisies suivantes pour le même jour :
08H=>12H30
12H30=>18H
Ce qui était un peu sévère, si une personne croit qu'elle va prendre son après midi, puis change d'avis et fait une journée continue de 10H...
Donc j'ai conscience que ça comptera 2 fois la minute de 12H30 dans la vue finale et que ça faussera légèrement le calcul, mais je préfère ça... Marge d'erreur d'une minute, c'est pas la mort, plutôt que de bloquer totalement une saisie qui est légitime.
Alors bref, je veux une date strictement inférieure ou supérieure pour considérer qu'il y a vraiment chevauchement...
Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13 CREATE TRIGGER no_insert_overlapping BEFORE INSERT ON horaire IF EXISTS ( SELECT * FROM horaire WHERE STR_TO_DATE(CONCAT(jour, ' ', debut), '%Y-%m-%d %H:%i:%s') < NEW.STR_TO_DATE(CONCAT(jour, ' ', fin), '%Y-%m-%d %H:%i:%s') AND STR_TO_DATE(CONCAT(jour, ' ', fin), '%Y-%m-%d %H:%i:%s') > NEW.STR_TO_DATE(CONCAT(jour, ' ', debut), '%Y-%m-%d %H:%i:%s') ) THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Insertion impossible car chevauchement de date !'; END IF;
Partager