Ci-dessous, les différences entre deux révisions de la page.
| Les deux révisions précédentes Révision précédente Prochaine révision | Révision précédente | ||
|
tips_informatiques:bases_de_donnees:mysql:mysql [2010/02/03 11:29] nico |
tips_informatiques:bases_de_donnees:mysql:mysql [2013/08/06 11:37] (Version actuelle) nico |
||
|---|---|---|---|
| Ligne 119: | Ligne 119: | ||
| BEFORE UPDATE ON `mytable` | BEFORE UPDATE ON `mytable` | ||
| FOR EACH ROW SET new.modified = NOW() | FOR EACH ROW SET new.modified = NOW() | ||
| + | </code> | ||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | ====== Créer un 'index unique' sur 2 paires différentes dans la même table ====== | ||
| + | |||
| + | __Soft__: MySQL Ver 5.1 | ||
| + | |||
| + | __Problème__: | ||
| + | |||
| + | Comment s'assurer que les paires field1-field2 soient uniques et que les paires field1-field3 soient uniques, sachant que field2 __ou__ field3 peuvent être données. | ||
| + | |||
| + | __Solution__: | ||
| + | |||
| + | - créer un champ "unique_index" | ||
| + | - créer un index unique sur ce champ "unique_index" | ||
| + | - créer des triggers BEFORE INSERT et BEFORE UPDATE pour remplir automatiquement ce champ "unique_index", en fonction de la présence de valeurs pour les champs field2 ou field3 | ||
| + | |||
| + | <code sql> | ||
| + | CREATE TABLE IF NOT EXISTS `my_table` ( | ||
| + | `id` int(11) NOT NULL AUTO_INCREMENT, | ||
| + | `unique_key` varchar(50) NOT NULL, | ||
| + | `field1` int(11) NOT NULL, | ||
| + | `field2` int(11) default NULL, | ||
| + | `field3` varchar(256) default NULL, | ||
| + | PRIMARY KEY (`id`), | ||
| + | UNIQUE KEY `unique_key` (`unique_key`) | ||
| + | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; | ||
| + | </code> | ||
| + | |||
| + | <code sql> | ||
| + | delimiter $$ | ||
| + | CREATE TRIGGER insert_unique_key | ||
| + | BEFORE INSERT ON my_table | ||
| + | FOR EACH ROW | ||
| + | BEGIN | ||
| + | IF NEW.field2 IS NULL OR NEW.field2 = '' THEN | ||
| + | SET NEW.unique_key=CONCAT(NEW.field1, '$$$', MD5(NEW.field3)); | ||
| + | ELSE | ||
| + | SET NEW.unique_key=CONCAT(NEW.field1, '***', NEW.field2); | ||
| + | END IF; | ||
| + | END; | ||
| + | $$ | ||
| + | </code> | ||
| + | |||
| + | <code sql> | ||
| + | delimiter $$ | ||
| + | CREATE TRIGGER update_unique_key | ||
| + | BEFORE UPDATE ON my_table | ||
| + | FOR EACH ROW | ||
| + | BEGIN | ||
| + | IF NEW.field2 IS NULL OR NEW.field2 = '' THEN | ||
| + | SET NEW.unique_key=CONCAT(NEW.field1, '$$$', MD5(NEW.field3)); | ||
| + | ELSE | ||
| + | SET NEW.unique_key=CONCAT(NEW.field1, '***', NEW.field2); | ||
| + | END IF; | ||
| + | END; | ||
| + | $$ | ||
| + | </code> | ||
| + | |||
| + | |||
| + | ====== DELETE avec sous-query ====== | ||
| + | |||
| + | __Soft__: MySQL Ver 5.0 | ||
| + | |||
| + | __Problème__: | ||
| + | |||
| + | Un DELETE avec une sous-query qui concerne la table dans laquelle des records doivent être effacés ne fonctionne pas directement. | ||
| + | |||
| + | Cette requête ne marche pas: | ||
| + | |||
| + | <code sql> | ||
| + | DELETE FROM bibliographies | ||
| + | WHERE bibliographies.id IN | ||
| + | ( | ||
| + | SELECT bibliographies.id | ||
| + | FROM bibliographies | ||
| + | WHERE document_id IN | ||
| + | ( | ||
| + | SELECT documents.id | ||
| + | FROM documents | ||
| + | WHERE document_subtype_id = 19 | ||
| + | ) | ||
| + | ) | ||
| + | </code> | ||
| + | |||
| + | L'erreur suivante est obtenue: //#1093 - You can't specify target table 'bibliographies' for update in FROM clause// | ||
| + | |||
| + | __Solution__: | ||
| + | |||
| + | Il suffit de rajouter un SELECT autour de la sous-query pour que la requête passe: | ||
| + | |||
| + | |||
| + | <code sql> | ||
| + | DELETE FROM bibliographies | ||
| + | WHERE bibliographies.id IN | ||
| + | ( | ||
| + | SELECT * FROM | ||
| + | ( | ||
| + | SELECT bibliographies.id | ||
| + | FROM bibliographies | ||
| + | WHERE document_id IN | ||
| + | ( | ||
| + | SELECT documents.id | ||
| + | FROM documents | ||
| + | WHERE document_subtype_id = 19 | ||
| + | ) | ||
| + | ) AS tmp | ||
| + | ) | ||
| </code> | </code> | ||