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> | ||