Précédent   Forum des professionnels en informatique > Bases de données > MySQL > Requêtes
Requêtes Forum d'entraide sur les requêtes MySQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 22/06/2011, 11h26   #1
Invité de passage
 
Inscription : septembre 2009
Messages : 15
Détails du profil
Informations forums :
Inscription : septembre 2009
Messages : 15
Points : 2
Points : 2
Par défaut DELETE dans des tables potentiellement vides

Bonjour à tous,

Je rencontre un petit soucis tout bête pour lequel je suis sûr qu'il existe une solution toute simple

Je voudrais pouvoir supprimer l'intégralité des informations relatives à un même membre dans toutes mes tables d'un coup. Pour cela j'ai un index commun à toutes les tables : id_membre. Je me suis donc naturellement tourné vers la solution suivante :

Code :
1
2
DELETE FROM table1, table2, table3 
WHERE id_membre= 1

Mon problème vient du fait que selon les membres, il est possible que certaines tables ne contiennent aucune ligne commençant par l'id_membre correspondant. Du coup la requête basique suivante ne peut pas fonctionner correctement et renvoie une erreur "die" qui bloque toute la requête.

Existe-t-il une solution simple et légère ? Dans le pire des cas j'ai la possibilité de tester la présence d'information dans chaque table et de supprimer ou non selon le résultat... Mais cette solution n'est ni simple ni légère

Merci d'avance à ceux qui pourront me renseigner
Mr_SATAN est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/06/2011, 11h41   #2
Expert Confirmé
 
Avatar de Maljuna Kris
 
Homme Avcxjo MoKo
Retraité
Inscription : novembre 2005
Messages : 2 530
Détails du profil
Informations personnelles :
Nom : Homme Avcxjo MoKo
Âge : 60

Informations professionnelles :
Activité : Retraité
Secteur : Administration - Collectivité locale

Informations forums :
Inscription : novembre 2005
Messages : 2 530
Points : 3 523
Points : 3 523
Saluton,
Si les tables ont été créées avec le moteur InnoDB, que la colonne id_membre est une clé étrangère dans les tables table2, table3 et que la déclaration de clé comporte la clause ON DELETE CASCADE, supprimer une valeur dans table1 la supprimera dans les autres tables.
Sinon, il te faudra faire 3 requêtes.
__________________
Kie lumo eksistas ankaŭ ombro troviĝas. L.L. Zamenhof
articles : Comment émuler un tableau croisé [quasi] dynamique
et : Une énigme mathématique résolue avec MySQL
recommande l'utilisation de PDO (PHP5 Data Objects)
Maljuna Kris est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/06/2011, 11h45   #3
Invité de passage
 
Inscription : septembre 2009
Messages : 15
Détails du profil
Informations forums :
Inscription : septembre 2009
Messages : 15
Points : 2
Points : 2
Merci pour ta réponse Maljuna Kris

Je n'ai pas tout compris, du coup je pense que les réponses à tes questions sont toutes "non"
Les tables sont créées tout simplement dans phpmyadmin

Donc tu confirmes que je n'aurai pas d'autres choix que de créer une requête par table en testant la présence de mon id_membre dans chacune ?
Mr_SATAN est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/06/2011, 11h46   #4
ced
Rédacteur/Modérateur

 
Avatar de ced
 
Homme Cédric Duprez
Inscription : avril 2002
Messages : 3 823
Détails du profil
Informations personnelles :
Nom : Homme Cédric Duprez
Âge : 36
Localisation : France, Loiret (Centre)

Informations professionnelles :
Secteur : Agroalimentaire - Agriculture

Informations forums :
Inscription : avril 2002
Messages : 3 823
Points : 6 437
Points : 6 437
MySQL possède une version multi-table du DELETE, dans laquelle on peut faire figurer des jointures.
La syntaxe suivante devrait passer :
Code :
1
2
3
4
DELETE t1, t2, t3
FROM table1 t1
LEFT JOIN table2 t2 ON t1.id_membre = t2.id_membre
LEFT JOIN table3 t3 ON t1.id_membre = t3.id_membre
2 remarques importantes :
  • si les tables sont en InnoDB, avec un clé étrangère entre les tables, alors il faut utiliser la clause ON DELETE CASCADE, comme suggéré par Maljuna Kris, parce que la syntaxe ci-dessus risque d'échouer à cause de la contrainte de clé étrangère
  • Il faut choisir judicieusement la table1, en prenant celle qui contient tous les id_membre à supprimer. En effet, MySQL ne disposant pas du FULL OUTER JOIN, il faut mettre en première table celle qui contient tous les id_membre, puis faire des jointures externes à gauche.
__________________
Rédacteur / Modérateur SGBD
Mes tutoriels et la FAQ MySQL

----------------------------------------------------
Pensez aux balises code et au tag
Je ne réponds pas aux questions techniques par message privé, les forums sont là pour ça
ced est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/06/2011, 11h49   #5
Expert Confirmé
 
Avatar de Maljuna Kris
 
Homme Avcxjo MoKo
Retraité
Inscription : novembre 2005
Messages : 2 530
Détails du profil
Informations personnelles :
Nom : Homme Avcxjo MoKo
Âge : 60

Informations professionnelles :
Activité : Retraité
Secteur : Administration - Collectivité locale

Informations forums :
Inscription : novembre 2005
Messages : 2 530
Points : 3 523
Points : 3 523
Ah oui, je n'avais pas pensé au LEFT JOIN, bien vu ced, comme d'hab.
__________________
Kie lumo eksistas ankaŭ ombro troviĝas. L.L. Zamenhof
articles : Comment émuler un tableau croisé [quasi] dynamique
et : Une énigme mathématique résolue avec MySQL
recommande l'utilisation de PDO (PHP5 Data Objects)
Maljuna Kris est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/06/2011, 11h55   #6
Invité de passage
 
Inscription : septembre 2009
Messages : 15
Détails du profil
Informations forums :
Inscription : septembre 2009
Messages : 15
Points : 2
Points : 2
Ok, je vais me pencher sur la question

A quoi correspondent t1, t2, t3 ?
Mr_SATAN est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/06/2011, 12h34   #7
Expert Confirmé
 
Avatar de Maljuna Kris
 
Homme Avcxjo MoKo
Retraité
Inscription : novembre 2005
Messages : 2 530
Détails du profil
Informations personnelles :
Nom : Homme Avcxjo MoKo
Âge : 60

Informations professionnelles :
Activité : Retraité
Secteur : Administration - Collectivité locale

Informations forums :
Inscription : novembre 2005
Messages : 2 530
Points : 3 523
Points : 3 523
Aux alias des tables dans la clause FROM et les jointures.
__________________
Kie lumo eksistas ankaŭ ombro troviĝas. L.L. Zamenhof
articles : Comment émuler un tableau croisé [quasi] dynamique
et : Une énigme mathématique résolue avec MySQL
recommande l'utilisation de PDO (PHP5 Data Objects)
Maljuna Kris est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/06/2011, 13h32   #8
Invité de passage
 
Inscription : septembre 2009
Messages : 15
Détails du profil
Informations forums :
Inscription : septembre 2009
Messages : 15
Points : 2
Points : 2
Ahah, je viens de supprimer la totalité de ma base de donnée en testant la requête ci-dessus Heureusement que je suis dans la phase de test, du coup j'avais que du faux contenu

La bonne nouvelle c'est que ça a l'air de fonctionner puisqu'aucune suppression n'a échouée. Il faut juste que j'arrive à limiter à l'id_membre concerné.
J'ai essayé la requête suivante, sans succès :

Code :
1
2
3
4
5
6
7
8
 
IF(isset($suppr)) 
	{
	$sql = mysqli_query($connexion, "DELETE t1, t2, t3
	FROM table1 WHERE id_membre = '".$suppr."' t1
	LEFT JOIN table1 t2 ON t1.id_membre = t2.id_client
	LEFT JOIN table1 t3 ON t1.id_membre = t3.id_client");
	}
Il faut peut-être que je place ma clause WHERE ailleurs ?
Mr_SATAN est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/06/2011, 14h59   #9
ced
Rédacteur/Modérateur

 
Avatar de ced
 
Homme Cédric Duprez
Inscription : avril 2002
Messages : 3 823
Détails du profil
Informations personnelles :
Nom : Homme Cédric Duprez
Âge : 36
Localisation : France, Loiret (Centre)

Informations professionnelles :
Secteur : Agroalimentaire - Agriculture

Informations forums :
Inscription : avril 2002
Messages : 3 823
Points : 6 437
Points : 6 437
Oui, la clause WHERE se met après les jointures.
Au passage, si id_membre est un entier, inutile de mettre la valeur entre quotes.
__________________
Rédacteur / Modérateur SGBD
Mes tutoriels et la FAQ MySQL

----------------------------------------------------
Pensez aux balises code et au tag
Je ne réponds pas aux questions techniques par message privé, les forums sont là pour ça
ced est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/06/2011, 15h18   #10
Invité de passage
 
Inscription : septembre 2009
Messages : 15
Détails du profil
Informations forums :
Inscription : septembre 2009
Messages : 15
Points : 2
Points : 2
Ok, merci beaucoup pour les conseils que vous m'avez donné.
Malheureusement ça ne fonctionne pas, du coup je vais peut-être me tourner vers une solution plus dans mes cordes. N'ayant jamais entendu parler de clé étrangères ou de DELETE ON CASCADE je risque de bidouiller pendant des jours pour faire quelque chose que je ne comprends pas.

C'est quand même dingue qu'il soit si difficile de faire comprendre à SQL que si une table ne contient pas l'ID demandée on laisse tomber et on passe à la table suivante... Ça semble tellement simple sur le papier...
Je me dirige vers une solution PHP avec un foreach. J'ai toujours le même soucis de plantage quand l'ID n'est pas présente mais je perd pas espoir


EDIT :

Voilà la solution que j'ai appliqué pour contourner le problème. Vu le nombre de topics trouvés sur Google, ça pourra peut-être servir à quelqu'un :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 
IF(isset($suppr)) 
	{
	// Test de présence de l'id dans les tables
	$tables = array("table1", "table2", "table3", "table4", "table5", "table6", "table7", "table8", "table9", "table10");
	foreach($tables as $table)
		{
		$rq = mysqli_query($connexion, "SELECT * FROM ".$table." WHERE id_membre = '".$suppr."'");
		$num_rows = mysqli_num_rows($rq);
		if($num_rows > 0)
			{
			$sql = mysqli_query($connexion, "DELETE FROM ".$table." WHERE id_membre = '".$suppr."'")
			or die("Suppression Impossible !");	
			}
		}
Pour résumer en français : on crée une boucle pour tester la présence de l'ID du membre concerné. Si l'ID est présente ($num_rows > 0) dans la table on efface les lignes concernées sinon on passe à la suivante
Mr_SATAN est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/06/2011, 16h03   #11
Expert Confirmé
 
Avatar de Maljuna Kris
 
Homme Avcxjo MoKo
Retraité
Inscription : novembre 2005
Messages : 2 530
Détails du profil
Informations personnelles :
Nom : Homme Avcxjo MoKo
Âge : 60

Informations professionnelles :
Activité : Retraité
Secteur : Administration - Collectivité locale

Informations forums :
Inscription : novembre 2005
Messages : 2 530
Points : 3 523
Points : 3 523
Citation:
Envoyé par Mr_SATAN Voir le message
Ok, merci beaucoup pour les conseils que vous m'avez donné.
Malheureusement ça ne fonctionne pas
Mais encore ?
__________________
Kie lumo eksistas ankaŭ ombro troviĝas. L.L. Zamenhof
articles : Comment émuler un tableau croisé [quasi] dynamique
et : Une énigme mathématique résolue avec MySQL
recommande l'utilisation de PDO (PHP5 Data Objects)
Maljuna Kris est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/06/2011, 17h30   #12
ced
Rédacteur/Modérateur

 
Avatar de ced
 
Homme Cédric Duprez
Inscription : avril 2002
Messages : 3 823
Détails du profil
Informations personnelles :
Nom : Homme Cédric Duprez
Âge : 36
Localisation : France, Loiret (Centre)

Informations professionnelles :
Secteur : Agroalimentaire - Agriculture

Informations forums :
Inscription : avril 2002
Messages : 3 823
Points : 6 437
Points : 6 437
Citation:
Envoyé par Mr_SATAN Voir le message
C'est quand même dingue qu'il soit si difficile de faire comprendre à SQL que si une table ne contient pas l'ID demandée on laisse tomber et on passe à la table suivante... Ça semble tellement simple sur le papier...
C'est parce que le SQL suit une logique ensembliste, et non pas ligne à ligne comme un langage de programmation.
__________________
Rédacteur / Modérateur SGBD
Mes tutoriels et la FAQ MySQL

----------------------------------------------------
Pensez aux balises code et au tag
Je ne réponds pas aux questions techniques par message privé, les forums sont là pour ça
ced est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 05h34.


 
 
 
 
Partenaires

Hébergement Web