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

SQL Procédural MySQL Discussion :

Récupérer ID à supprimer (venant de la requête) dans un Trigger


Sujet :

SQL Procédural MySQL

  1. #1
    Membre actif
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    101
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 101
    Par défaut Récupérer ID à supprimer (venant de la requête) dans un Trigger
    Bonjour,

    Mes quelques recherches sur le forum ont étés vaines et bien q'un post porte à peu près le même nom que le mien, la solution apporté n'est pas celle que je veux.

    Je vous explique..
    J'ai 4 tables dans ma base de données qui ont toute en commun un champ qui est lié à l'identifiant (auto_increment) d'une 5ème table
    Ainsi les tables A, B, C et D ont toutes un champ "id_secret" (ce n'est pas un auto_increment) dont la valeur correspond à une ligne de la table E.

    Lorsque je lance la requête de suppression d'un élément X d'une table (grace a son identifiant et son titre), je souhaite qu'avant la suppression un trigger se déclenche, qu'il récupère l'identifiant et le titre et se serve de l'identifiant pour la supprimer la ligne correspondante dans la table E.

    Mon soucis c'est que je ne sait pas et ne trouve pas comment dans mon Trigger je peux récupérer l'identifiant et le titre se trouvant dans la requête de suppression.

    Je sais que je peux passer par ON DELETE CASCADE mais je fais cela pour une épreuve pratique pour mon BTS et je dois faire un Trigger.

    Merci d'avance pour votre aide.

  2. #2
    Rédacteur/Modérateur

    Avatar de Antoun
    Homme Profil pro
    Architecte décisionnel
    Inscrit en
    Octobre 2006
    Messages
    6 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Architecte décisionnel
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2006
    Messages : 6 287
    Par défaut
    a priori, l'identifiant supprimé est old.ID (si ta colonne d'identifiants s'appelle ID).

  3. #3
    Membre actif
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    101
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 101
    Par défaut
    Mais vu que mon Trigger se déclenche avant c'est bien OLD ? Pas plutot NEW ?

  4. #4
    Rédacteur/Modérateur

    Avatar de Antoun
    Homme Profil pro
    Architecte décisionnel
    Inscrit en
    Octobre 2006
    Messages
    6 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Architecte décisionnel
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2006
    Messages : 6 287
    Par défaut
    Non, old et new ne dépendent pas de la distinction BEFORE/AFTER. Du coup, dans un ON DELETE, il n'y a que du old.

  5. #5
    Membre actif
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    101
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 101
    Par défaut
    Ok Je test ca alors et te tient au courant
    Merci

    [EDIT]

    J'ai essayé ca mais a chaque fois ca me dit que j'ai une erreur dans ma synthaxe SQL :S

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    CREATE TRIGGER delete_secret BEFORE DELETE ON LICENCE
            FOR EACH ROW
    	BEGIN
    		DECLARE identifiant INT;
    		DECLARE titre VARCHAR;
     
    		SET identifiant = OLD.id_licence ;
    		SELECT titre FROM SECRET WHERE id_secret = identifiant INTO titre;
     
    		DELETE FROM SECRET WHERE id_secret = identifiant AND titre = titre;
    	END
    [/EDIT]

  6. #6
    Membre actif
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    101
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 101
    Par défaut
    Une question autre lié a ca.. Je met mon Trigger en BEFORE, donc dés que le serveur MySQL recoit la requete de DELETE il lance le Trigger mais une fois le trigger exécuté est-ce que la requete DELETE de fait ou pas ?

  7. #7
    Rédacteur/Modérateur

    Avatar de Antoun
    Homme Profil pro
    Architecte décisionnel
    Inscrit en
    Octobre 2006
    Messages
    6 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Architecte décisionnel
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2006
    Messages : 6 287
    Par défaut
    Elle se fait, sauf si ton trigger provoque une erreur.

  8. #8
    Membre actif
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    101
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 101
    Par défaut
    Tu as une idée de pourquoi la reauete de creation du trigger ne fonctionne pas ?
    J'ai testé plusieurs fois en changeant les variables de @mavar à mavar
    J'ai aussi changé le titre = SELECT ... en SELECT ... INTO mavar ..

    Mais toujours une erreur de synthaxe a ce niveau la :s

    Voici l'erreur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '; SET identifiant = OLD.id_licence ; SELECT titre FROM SECRET WHERE id' at line 5
    J'ai essayé en important le fichier dans lequel j'avais déclaré le délimiteur mais toujours la même erreur.. :s

  9. #9
    Rédacteur/Modérateur

    Avatar de Antoun
    Homme Profil pro
    Architecte décisionnel
    Inscrit en
    Octobre 2006
    Messages
    6 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Architecte décisionnel
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2006
    Messages : 6 287
    Par défaut
    Désolé, j'avais raté ton message au-dessus...

    La gestion des BEGIN/END n'est pas toujours très simple... Quel client utilises-tu ?

    Pour + d'info, voir le paragraphe "A propos du délimiteur" dans cet article :
    http://alain-defrance.developpez.com...-error/#LIII-A

  10. #10
    Membre actif
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    101
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 101
    Par défaut
    PHP MyAdmin.

  11. #11
    Rédacteur/Modérateur

    Avatar de Antoun
    Homme Profil pro
    Architecte décisionnel
    Inscrit en
    Octobre 2006
    Messages
    6 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Architecte décisionnel
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2006
    Messages : 6 287
    Par défaut
    dans ce cas, il faut que tu indiques à phpMyAdmin un autre séparateur que le point-virgule (détails dans l'article cité plus-haut).

  12. #12
    Membre actif
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    101
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 101
    Par défaut
    Que dois-je exactement écrire dans la fenêtre de requête car j'ai testé plusieurs trucs et je rien ne marche. J'ai surement pas encore testé la solution qui fonctionne mais faut-il encore que je la trouve lol

    [EDIT]
    Je viens de tester encore ca :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    CREATE TRIGGER `delete_secret` BEFORE DELETE ON `LICENCE`
    FOR EACH ROW
           BEGIN
                    DECLARE identifiant INT;
            	DECLARE title VARCHAR;
     
    		SET identifiant = OLD.id_licence ;
    		SELECT titre INTO title FROM SECRET WHERE id_secret = identifiant;
     
    		DELETE FROM SECRET WHERE id_secret = identifiant AND titre = title;
    	END//
    En mettant // comme délimiteur dans le petit input de phpMyAdmin mais ca ne fonctionne tjr ppas et j'ai l'erreur suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '; SET identifiant = OLD.id_licence ; SELECT titre INTO title FROM SECRET' at line 5
    C'est pas faute d'essayer car j'ai essayé en mettant les DECLARE avant le BEGIN, en mettant un point virgule avant le délimiteur sur le dernier END, j'ai essayé de mettre des @ devant les variables, différentes synthaxes sur le SET de mon title, d'ailleurs je l'ai appellé title car il s'appellé titre tout comme un des champs ca aurait foutu le brin :/
    Bref pour le moment toujours la même erreur -_-

  13. #13
    Rédacteur/Modérateur

    Avatar de Antoun
    Homme Profil pro
    Architecte décisionnel
    Inscrit en
    Octobre 2006
    Messages
    6 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Architecte décisionnel
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2006
    Messages : 6 287
    Par défaut
    Il doit rester une ou plusieurs petites erreurs... donne-moi le code de création de tes tables, que je puisse tester.

  14. #14
    Membre actif
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    101
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 101
    Par défaut
    Ba ouai, je test dans Sequel Pro mais ca ne fonctionne pas mieux -_-

    Voici le code de création des tables, via une exportation dans PHPMyAdmin :

    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
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    CREATE TABLE `CB` (
      `id_cb` int(5) NOT NULL,
      `titulaire` varchar(75) COLLATE utf8_unicode_ci DEFAULT NULL,
      `num` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL,
      `date_expiration` varchar(10) CHARACTER SET utf8 DEFAULT NULL,
      `type_cb` varchar(25) COLLATE utf8_unicode_ci DEFAULT NULL,
      PRIMARY KEY (`id_cb`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
     
    CREATE TABLE `COMPTE` (
      `id_compte` int(5) NOT NULL,
      `banque_name` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL,
      `num` varchar(50) CHARACTER SET utf8 DEFAULT NULL,
      `type_compte` varchar(50) CHARACTER SET utf8 DEFAULT NULL,
      PRIMARY KEY (`id_compte`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
     
    CREATE TABLE `LICENCE` (
      `id_licence` int(5) NOT NULL,
      `application` varchar(50) CHARACTER SET utf8 DEFAULT NULL,
      `version` varchar(15) CHARACTER SET utf8 DEFAULT NULL,
      `description` text CHARACTER SET utf8,
      `societe` varchar(75) COLLATE utf8_unicode_ci DEFAULT NULL,
      `url` varchar(200) CHARACTER SET utf8 DEFAULT NULL,
      `num` varchar(100) CHARACTER SET utf8 DEFAULT NULL,
      `clef` varchar(100) CHARACTER SET utf8 DEFAULT NULL,
      `date_achat` varchar(10) CHARACTER SET utf8 DEFAULT NULL,
      `nom` varchar(100) CHARACTER SET utf8 DEFAULT NULL,
      `email` varchar(150) COLLATE utf8_unicode_ci DEFAULT NULL,
      `notes` text COLLATE utf8_unicode_ci,
      PRIMARY KEY (`id_licence`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
     
    CREATE TABLE `SECRET` (
      `id_secret` int(5) NOT NULL AUTO_INCREMENT,
      `titre` varchar(50) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
      PRIMARY KEY (`id_secret`)
    ) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=65 ;
     
    CREATE TABLE `SITE` (
      `id_site` int(5) NOT NULL,
      `utilisateur` varchar(35) CHARACTER SET utf8 DEFAULT NULL,
      `password` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL,
      `url` varchar(200) COLLATE utf8_unicode_ci DEFAULT NULL,
      `description` text COLLATE utf8_unicode_ci,
      PRIMARY KEY (`id_site`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

  15. #15
    Membre actif
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    101
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 101
    Par défaut
    Je viens d'essayer aussi de mettre des @ devant les variables sauf dans le DECLARE en vain.. je sais si c'est sur PHPMyAdmin que je dois gueuler ou MySQL mais ca devient chiant. Et si je pouvais m'en passer je le ferais mais pour mon epreuve pratique je suis obligé d'avoir ce trigger -_- grrr

  16. #16
    Rédacteur/Modérateur

    Avatar de Antoun
    Homme Profil pro
    Architecte décisionnel
    Inscrit en
    Octobre 2006
    Messages
    6 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Architecte décisionnel
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2006
    Messages : 6 287
    Par défaut
    Bon, il manquait juste la taille après VARCHAR :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    CREATE TRIGGER `delete_secret` BEFORE DELETE ON `LICENCE`
    FOR EACH ROW
      BEGIN
        declare identifiant int ;
        declare title varchar(255) ;
        SET identifiant = OLD.id_licence ;
        SELECT titre INTO title FROM SECRET WHERE id_secret = identifiant ;
        DELETE FROM SECRET WHERE id_secret = identifiant AND titre = title ;
      END ;
    Tu peux aussi simplifier tout ça en ne mettant qu'une seule requête dans le trigger, ce qui permet de se passer du BEGIN... END et des histoires de délimiteur.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    CREATE TRIGGER `delete_secret` BEFORE DELETE ON `LICENCE`
    FOR EACH ROW
      DELETE FROM SECRET 
      WHERE id_secret = OLD.id_licence 
        AND titre = (SELECT titre FROM SECRET WHERE id_secret = OLD.id_licence) ;

  17. #17
    Membre actif
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    101
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 101
    Par défaut
    Oh YEEES Merci ca fonctionne, l'insertion reste a voir si lors d'une suppression il s'execute correctement mais waou encore un truc tout con mais j'ai cru que j'en verrais jamais le bout lol

    Je le test en "prod"

  18. #18
    Membre actif
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    101
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 101
    Par défaut
    Je viens de tester, j'ai mis comme trigger la version "courte" que tu m'as donnée.

    J'ai ensuite testé aussi bien dans mon appli que ds PHPMyAdmin et j'obtient l'erreur suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #1093 - You can't specify target table 'SECRET' for update in FROM clause
    Je comprend pas bien le prob :/

    [EDIT] Apparement je ne peut pas faire une sous-requete SELECT sur la meme table que la requete UPDATE/DELETE dans laquelle elle se trouve.
    Si je passe par une variable et donc par la version "longue" du trigger ca devrait fonctionner .. je vais tester.. [/EDIT]

  19. #19
    Membre actif
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    101
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 101
    Par défaut
    J'ai maintenant mis le trigger en version "longue" et quand j'essai de supprimer j'ai une erreur..différente, la voici :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #1267 - Illegal mix of collations (utf8_unicode_ci,IMPLICIT) and (utf8_general_ci,IMPLICIT) for operation '='


    [EDIT] J'ai fait quelques recherche c'était un problème d'interclassement ..
    Bref j'ai exporté les tables viré tout les truc relatif à l'interclassement des tables et champs, supprimer la base, recréé base + tables, j'ai remis le trigger version longue et c'est bon ca fonctionne

    Merci beaucoup pour ton aide précieuse
    [/EDIT]

  20. #20
    Rédacteur/Modérateur

    Avatar de Antoun
    Homme Profil pro
    Architecte décisionnel
    Inscrit en
    Octobre 2006
    Messages
    6 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Architecte décisionnel
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2006
    Messages : 6 287
    Par défaut
    Citation Envoyé par Tibimac Voir le message
    [EDIT] Apparement je ne peut pas faire une sous-requete SELECT sur la meme table que la requete UPDATE/DELETE dans laquelle elle se trouve.
    Si je passe par une variable et donc par la version "longue" du trigger ca devrait fonctionner .. je vais tester.. [/EDIT]
    yep, le contournement est le suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    CREATE TRIGGER `delete_secret` BEFORE DELETE ON `LICENCE`
    FOR EACH ROW
      DELETE FROM SECRET 
      WHERE id_secret = OLD.id_licence 
        AND titre = (SELECT titre FROM (SELECT titre FROM SECRET) WHERE id_secret = OLD.id_licence) ;
    explication : la (sous-)sous-requête dans le FROM est implémentée par une table temporaire, du coup ça n'est plus la même table...

    En l'occurence, il est sans doute préférable d'utiliser une variable locale comme tu l'as fait...

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Réponses: 2
    Dernier message: 15/05/2014, 11h58
  2. Réception requête dans fonction trigger
    Par dib258 dans le forum Requêtes
    Réponses: 7
    Dernier message: 04/12/2011, 16h57
  3. [SQL SERVER 2005]problème requête dans un trigger
    Par Kropernic dans le forum Développement
    Réponses: 14
    Dernier message: 02/03/2010, 18h20
  4. Réponses: 3
    Dernier message: 03/12/2005, 16h56
  5. Réponses: 7
    Dernier message: 30/06/2005, 10h06

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