[resolu]Delete cascade sans utiliser les foreign keys oO

Delete cascade sans utiliser les foreign keys oO [resolu] - SQL/NoSQL - Programmation

Marsh Posté le 19-11-2006 à 22:13:42    

Bonjour,
J'ai un soucis dont je ne comprends pas l'origine. J'utilise une base de données mysql 5, mes tables sont en MyISAM.
 
Je vous montre tout d'abord un dump de la structure de ma base :
 

-- phpMyAdmin SQL Dump
-- version 2.6.2-pl1
-- http://www.phpmyadmin.net
--  
-- Serveur: localhost
-- Généré le : Dimanche 19 Novembre 2006 à 21:30
-- Version du serveur: 5.0.24
-- Version de PHP: 5.0.4
--  
-- Base de données: `elico_test`
--  
 
-- --------------------------------------------------------
 
--  
-- Structure de la table `actualites`
--  
 
CREATE TABLE `actualites` (
  `id` int(11) NOT NULL auto_increment,
  `auteur` varchar(32) collate utf8_bin NOT NULL,
  `date_year` varchar(4) collate utf8_bin NOT NULL,
  `date_month` varchar(2) collate utf8_bin NOT NULL,
  `date_day` varchar(2) collate utf8_bin NOT NULL,
  `titre` varchar(64) collate utf8_bin NOT NULL,
  `texte` text collate utf8_bin NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=39 DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=39 ;
 
 
--  
-- Structure de la table `equipes`
--  
 
CREATE TABLE `equipes` (
  `id` int(11) NOT NULL auto_increment,
  `nom` varchar(32) character set utf8 collate utf8_bin NOT NULL,
  `responsable` varchar(128) character set utf8 collate utf8_bin NOT NULL,
  `short_desc` tinytext character set utf8 collate utf8_bin NOT NULL,
  `long_desc` text character set utf8 collate utf8_bin NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=9 DEFAULT CHARSET=latin1 AUTO_INCREMENT=9 ;
 
 
--  
-- Structure de la table `groupes`
--  
 
CREATE TABLE `groupes` (
  `id` int(11) NOT NULL auto_increment,
  `groupe` varchar(128) character set utf8 collate utf8_bin NOT NULL,
  PRIMARY KEY  (`id`),
  UNIQUE KEY `groupe` (`groupe`)
) ENGINE=MyISAM AUTO_INCREMENT=6 DEFAULT CHARSET=latin1 AUTO_INCREMENT=6 ;
 
 
--  
-- Structure de la table `personnel`
--  
 
CREATE TABLE `personnel` (
  `id` int(11) NOT NULL auto_increment,
  `prenom` varchar(32) collate utf8_bin NOT NULL,
  `nom` varchar(32) collate utf8_bin NOT NULL,
  `email` varchar(128) collate utf8_bin NOT NULL,
  `telephone` varchar(16) collate utf8_bin NOT NULL,
  `tutelle` varchar(16) collate utf8_bin NOT NULL,
  `fonction` varchar(16) collate utf8_bin NOT NULL,
  `groupe` int(11) NOT NULL,
  `equipe` varchar(16) collate utf8_bin NOT NULL,
  `localisation` varchar(16) collate utf8_bin NOT NULL,
  PRIMARY KEY  (`id`),
  KEY `groupe` (`groupe`)
) ENGINE=MyISAM AUTO_INCREMENT=88 DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=88 ;
 


 
Comme vous le voyez, il n'y a que des Primary keys (normal) et quelques index. Aucune définition de clefs étrangères (même si j'en utilise, personnel.groupe et personnel.equipe sont des entiers contenant l'id d'un enregistrement des tables correspondantes).
 
Mon problème maintenant : Quand je fais un 'DELETE FROM equipes WHERE id = 1' par exemple, ça me supprime tout les enregistrements de la table personnel où personnel.equipe = 1.
Pourtant je ne demande pas de delete cascade, il n'y a rien dans la structure de la base qui pourrait indiquer à mysql le lien entre les deux tables, donc je ne comprends pas :\
 
Si vous avez une idée du problème, ça m'aiderait pas mal, merci :)


Message édité par c0wb0y le 20-11-2006 à 18:57:41
Reply

Marsh Posté le 19-11-2006 à 22:13:42   

Reply

Marsh Posté le 20-11-2006 à 08:40:36    

tu peux faire un trigger

Reply

Marsh Posté le 20-11-2006 à 09:45:37    

Je viens d'aller voir la doc des TRIGGER sur mysql, et je ne vois pas vraiment comment ça peut m'aider. D'après ce que j'ai compris le trigger est là pour faire des vérifications avant de faire des modif' sur la table non ?
De plus, je ne suis pas sur que le serveur où sera hébergé le site au final sera sur mysql5 :/

Reply

Marsh Posté le 20-11-2006 à 10:55:03    

c0wb0y a écrit :

1] D'après ce que j'ai compris le trigger est là pour faire des vérifications avant de faire des modif' sur la table non ?
2] De plus, je ne suis pas sur que le serveur où sera hébergé le site au final sera sur mysql5 :/


 
1] Pas nécessairement. Un trigger peut servir à faire un update sur une table tierce quand tu modifies un champ dans une table. On peut aussi faire de la suppression en cascade avec un trigger.
 
2] C'est déjà plus gênant.
 
 

Reply

Marsh Posté le 20-11-2006 à 15:21:49    

c0wb0y a écrit :


De plus, je ne suis pas sur que le serveur où sera hébergé le site au final sera sur mysql5 :/


 
Avant de faire quoi que ce soit, Il faut que tu regardes sur ton hébergeur.  Car je me suis déja fait avoir ça
 
Aussi non, y a que les triggers comme solution

Reply

Marsh Posté le 20-11-2006 à 16:17:14    

Je crois que vous avez repondu à l'envers les gars.
 
Actuellement, il a un DELETE CASCADE sans l'avoir demandé.
 
Il ne veut pas de trigger pour simuler un DELETE CASCADE, il veut l'empêcher :o
 
Bon, donc 2 trucs :
1/ Vérifie que t'as PAS de triggers dans ta base.
2/ Comment détectes-tu que ta table "personnel" se vide en même temps que "equipes" ? Poste ta requête.
 
J'imagine (pour le 2) que tu fas une jointureentre personnel et equipes, et donc que personnel est toujours rempli, mais vu qu'il n'y a pas d'équipe, la requête ne retourne plus le personnel des équipes effacées.

Reply

Marsh Posté le 20-11-2006 à 16:40:34    

C'est tout à fait ça MagicBuzz, merci de recadrer les choses ^^

 

Pour l'existance des triggers, il n'y en a pas (base 'information_schema', table 'triggers' vide).

 

Pour le deuxième point,
La fonction de suppresion d'équipe est la suivante:

Code :
  1. static function delete($id){
  2.             $dbh = Database::getInstance()->getDbHandle();
  3.             $sql = 'DELETE FROM equipes '.
  4.                    'WHERE id=\''.$id.'\'';           
  5.             $dbh->query($sql) or die($dbh->errorInfo());           
  6.         }
 

Cette méthode se trouve dans la classe Equipe et je l'appelle donc par Equipe::delete(X);. J'ai aussi testé la requete directement dans phpmyadmin, les conséquences sont les mêmes, un 'select * from personnel where personnel.equipe = X' me renvoie 0.

 

Si tu veux plus de détails j'essayerai de les fournir dans la mesure du possible ^^

 

Merci de ton aide :)

 


PS : Sinon oui à un moment je fais une jointure entre ma table personnel et la table equipe. C'est lorsque je cherche à créer l'annuaire du personnel, je veux donc rattacher le nom de l'équipe à chaque personne.
La requete se présente ainsi:

Citation :


SELECT personnel.id, personnel.nom, {...}, equipes.nom as equipe
FROM personnel, equipes
WHERE personnel.equipe = equipes.id
ORDER BY personnel.nom


Message édité par c0wb0y le 20-11-2006 à 16:46:15
Reply

Marsh Posté le 20-11-2006 à 16:56:36    

Bah voilà :D
 
Si tu fais une jointure "inner join", alors il ne va retourner que les personnes qui sont dans une équipe EXISTANTE.
 
Donc tu dois passer par une jointure EXTERNE (left/right outer join) afin de rammener aussi les personnes qui n'ont plus d'équipe, ou simplement viter ta jointure, ça dépend des infos dont tu as besoin.
 
Mais je te rassure, "personnel" contient encore toutes les lignes.

Reply

Marsh Posté le 20-11-2006 à 18:57:28    

C'est parfait :D
 
Merci beaucoup MagicBuzz =)
 
(Va falloir que je lise quelques articles concernant les jointures, parcequ'on dirait que j'y comprends pas grand chose en fait  :whistle: )

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed