IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Requêtes MySQL Discussion :

DELETE avec contre-verification


Sujet :

Requêtes MySQL

  1. #1
    Modérateur
    Avatar de sabotage
    Homme Profil pro
    Inscrit en
    Juillet 2005
    Messages
    29 208
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juillet 2005
    Messages : 29 208
    Points : 44 155
    Points
    44 155
    Par défaut DELETE avec contre-verification
    Bonjour,

    J'ai une table de liaison entre des sociétés et des utilisateur structurée ainsi :

    t_compte
    ---
    id, societe, utilisateur, status

    status indique si l'utilisateur est "propriétaire" (1) ou "délégué" (0).
    seul le "propriétaire" d'une société peut supprimer des utilisateurs "délégué" de cette société.

    L'interface HTML/PHP transmet uniquement l'id à supprimer et l'utilisateur demandant la suppression.
    L'idée est donc de vérifier que l'utilisateur supprimant est bien "proprietaire" de la societé.

    J'ai écris une requete de suppression de "delegué" ainsi avec une sous-requete :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    DELETE FROM t_compte 
    WHERE id=12345 
       AND societe IN (
        SELECT societe 
        FROM t_compte 
        WHERE status = 1 
          AND utilisateur=toto
      )
    Est-ce que cela vous parrait bon ou completement nul ?

    Y a t'il une meilleur maniere de l'écrire en SQL ?

    L'alternative que j'avais étant de découper et utiliser le langage de programmation :
    1 - trouver la société correspondant à l'id
    2 - vérifier si l'utilisateur est "propriétaire" de cette société
    3 - si oui faire la suppression.

    Merci de votre aide.
    N'oubliez pas de consulter les FAQ PHP et les cours et tutoriels PHP

  2. #2
    ced
    ced est déconnecté
    Rédacteur/Modérateur

    Avatar de ced
    Homme Profil pro
    Gestion de bases de données techniques
    Inscrit en
    Avril 2002
    Messages
    6 016
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Gestion de bases de données techniques
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Avril 2002
    Messages : 6 016
    Points : 23 705
    Points
    23 705
    Par défaut
    Salut ,

    Est-ce que tu as testé la requête (dans une transaction, pour pouvoir revenir en arrière en cas de pépin, si tu es en InnoDB, bien sûr).
    Parce que je crois me souvenir d'un vieux bug MySQL toujours pas résolu qui empêche le DELETE (et l'UPDATE) avec une sous-requête sur la table dans laquelle on fait la mise à jour. Ca va générer un message d'erreur...

    Ensuite, il y a certaines choses que je ne comprends pas dans la requête. Est-ce que le champ id est la clé primaire de ta table ?
    Si oui, alors la sous-requête ne sert à rien, vu que tu limites la suppression à un seul id...

    ced
    Rédacteur / Modérateur SGBD et R
    Mes tutoriels et la FAQ MySQL

    ----------------------------------------------------
    Pensez aux balises code et au tag
    Une réponse vous a plu ? N'hésitez pas à y mettre un
    Je ne réponds pas aux questions techniques par message privé, les forums sont là pour ça

  3. #3
    Modérateur

    Avatar de MaitrePylos
    Homme Profil pro
    DBA
    Inscrit en
    Juin 2005
    Messages
    5 496
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : Belgique

    Informations professionnelles :
    Activité : DBA
    Secteur : Service public

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 496
    Points : 12 596
    Points
    12 596
    Par défaut
    Autre idée, autre code

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    SELECT IF(
      SELECT COUNT(societe) 
        FROM t_compte 
        WHERE STATUS = 1 
          AND utilisateur=toto > 0 ,DELETE FROM t_compte 
    WHERE id=12345 ,SELECT NULL )

  4. #4
    Modérateur
    Avatar de sabotage
    Homme Profil pro
    Inscrit en
    Juillet 2005
    Messages
    29 208
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juillet 2005
    Messages : 29 208
    Points : 44 155
    Points
    44 155
    Par défaut
    Est-ce que tu as testé la requête
    est-ce que j'etais trop pressé de rentrer chez moi ?
    empêche le DELETE (et l'UPDATE) avec une sous-requête sur la table dans laquelle on fait la mise à jour
    effectivement
    La solution pour mysql est d'utiliser une jointure :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    DELETE t1 FROM t_compte t1 JOIN t_compte t2 USING (societe)
     WHERE t1.id=12345 
    AND t2.utilisateur='toto' AND t2.status=1
    mais je ne sais pas si on doit qualifier ça d'astucieux ou d'ignoble.


    Est-ce que le champ id est la clé primaire de ta table ?
    Si oui, alors la sous-requête ne sert à rien, vu que tu limites la suppression à un seul id...
    oui c'est bien la clé primaire.
    le but de la sous requete n'est pas de limité les lignes concernés mais de garantir directement par la requete que l'utilisateur a le droit nécessaire pour effectuer la suppression.

    Pour la proposition de Maitre Pylos, visiblement mysql ne veut pas d'un DELETE en resultat d'un SELECT IF (la requete fonctionne si je mets un SELECT a la place du DELETE).
    N'oubliez pas de consulter les FAQ PHP et les cours et tutoriels PHP

  5. #5
    Modérateur

    Avatar de MaitrePylos
    Homme Profil pro
    DBA
    Inscrit en
    Juin 2005
    Messages
    5 496
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : Belgique

    Informations professionnelles :
    Activité : DBA
    Secteur : Service public

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 496
    Points : 12 596
    Points
    12 596
    Par défaut
    Au grand maux les grand moyens.

    Avec une store pro, pour éviter de faire la vérif dans PHP

    Code : 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
     
    DELIMITER $$
     
    DROP FUNCTION IF EXISTS `ta_base`.`prop_del_delegue`$$
    CREATE DEFINER=`root`@`localhost` FUNCTION `prop_del_delegue`(proprietaire varchar,id_delegue int) RETURNS TINYINT
    BEGIN
       DECLARE resultat TINYINT ;
       DECLARE compteur INT;
     
    SELECT COUNT(societe) 
    	FROM t_compte
    	 INTO compteur  
    WHERE STATUS = 1 
    AND utilisateur = proprietaire;
     
        IF (compteur > 0) THEN
    		DELETE FROM t_compte WHERE id = id_delegue
            SET resultat = 1;
        ELSE
            SET resultat = 0;
     
        END IF;
     
        RETURN resultat;
     
    END$$
     
    DELIMITER ;

  6. #6
    Modérateur
    Avatar de sabotage
    Homme Profil pro
    Inscrit en
    Juillet 2005
    Messages
    29 208
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juillet 2005
    Messages : 29 208
    Points : 44 155
    Points
    44 155
    Par défaut


    Merci pour votre aide.
    N'oubliez pas de consulter les FAQ PHP et les cours et tutoriels PHP

  7. #7
    Membre éprouvé Avatar de Oishiiii
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2009
    Messages
    508
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Août 2009
    Messages : 508
    Points : 1 104
    Points
    1 104
    Par défaut
    Petite info.

    Effectivement MySQL n'accepte pas ce genre de requêtes :
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    DELETE FROM t_compte 
    WHERE id=12345 
    AND societe IN (
        SELECT societe 
        FROM t_compte 
        WHERE STATUS = 1 
        AND utilisateur=toto
      )
    Impossible d'avoir une sous-requête portant sur la table concernée par le DELETE/UPDATE.
    Il y a une astuce qui est d'utiliser une table dérivée :
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    DELETE FROM t_compte 
    WHERE id=12345 
    AND societe IN (
        SELECT societe 
        FROM (SELECT * FROM t_compte) AS td
        WHERE STATUS = 1 
        AND utilisateur=toto
      )

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Delete avec polymorphisme
    Par taron dans le forum C++
    Réponses: 4
    Dernier message: 05/01/2006, 22h29
  2. Delete avec jointure impossible
    Par _developpeur_ dans le forum Access
    Réponses: 13
    Dernier message: 18/11/2005, 16h22
  3. dbexpress : delete avec paramètre
    Par KRis dans le forum Bases de données
    Réponses: 2
    Dernier message: 14/06/2005, 10h04
  4. DELETE avec sous-requête
    Par say dans le forum Langage SQL
    Réponses: 2
    Dernier message: 27/04/2005, 08h20
  5. INTERBASE: DELETE avec sous requete conditionnelle
    Par Papino dans le forum InterBase
    Réponses: 6
    Dernier message: 17/02/2005, 22h55

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo