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 :

Erreur SQL 1442 : Trigger Insert ne fonctionne pas


Sujet :

SQL Procédural MySQL

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2016
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 27
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2016
    Messages : 3
    Points : 1
    Points
    1
    Par défaut Erreur SQL 1442 : Trigger Insert ne fonctionne pas
    Bonjour,

    je réalise un trigger qui vérifie si la date de la séance (date_session) est 3 mois supérieur à la date de formation (Date_form) lors de l'insertion.

    Malheureusement lorsque je réalise les tests d'insertion je reçois comme erreur:
    " #1442 - Can't update table 'session' in stored function/trigger because it is already used by statement which invoked this stored function/trigger. "

    Après de nombreuses recherches, je reste coincé. j'espère donc que vous pourriez m'aider.

    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
     
    delimiter //
    CREATE TRIGGER chk_date_session
    BEFORE INSERT 
    ON session FOR EACH ROW
    BEGIN
     
    IF (select Date_form from formation, session 
            where formation.num_formation = session.num_formation
    	and DATE_ADD(Date_form, INTERVAL 3 MONTH) > NEW.date_session)
    THEN
            delete from session where num_session = new.num_session;
    END IF;
    END
    delimiter ;

  2. #2
    Membre émérite Avatar de vttman
    Homme Profil pro
    Développeur "couteau mosellan"
    Inscrit en
    Décembre 2002
    Messages
    1 140
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur "couteau mosellan"
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2002
    Messages : 1 140
    Points : 2 286
    Points
    2 286
    Par défaut
    Hello nekfeu,
    je n'ai pas triggerisé récemment mais ...

    En dehors de la syntaxe du select (voir jointure sql2)

    Je dirais qu'ici on teste une condition avant d'insérer dans la table session
    et si ça n'est pas bon on tente ici de détruire une ligne qui n'a pas été encore insérée
    d'où le message explicite d'erreur.

    Faire une recherche sur EXCEPTION pour gérer ce cas de figure
    Emérite, émérite je ne pense pas ... plutôt dans le développement depuis FORT FORT longtemps, c'est mon job, ça oui
    A part ça ... Il ne pleut jamais en Moselle !

  3. #3
    Membre confirmé Avatar de isabelle.letrong
    Femme Profil pro
    Conseil - Consultante en systèmes d'information
    Inscrit en
    Juillet 2010
    Messages
    109
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Conseil - Consultante en systèmes d'information
    Secteur : Conseil

    Informations forums :
    Inscription : Juillet 2010
    Messages : 109
    Points : 487
    Points
    487
    Par défaut Non inhibition d'une opération via trigger
    Citation Envoyé par Nekfeu Voir le message
    Bonjour,

    je réalise un trigger qui vérifie si la date de la séance (date_session) est 3 mois supérieur à la date de formation (Date_form) lors de l'insertion.

    Malheureusement lorsque je réalise les tests d'insertion je reçois comme erreur:
    " #1442 - Can't update table 'session' in stored function/trigger because it is already used by statement which invoked this stored function/trigger. "

    Après de nombreuses recherches, je reste coincé. j'espère donc que vous pourriez m'aider.

    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
     
    delimiter //
    CREATE TRIGGER chk_date_session
    BEFORE INSERT 
    ON session FOR EACH ROW
    BEGIN
     
    IF (select Date_form from formation, session 
            where formation.num_formation = session.num_formation
    	and DATE_ADD(Date_form, INTERVAL 3 MONTH) > NEW.date_session)
    THEN
            delete from session where num_session = new.num_session;
    END IF;
    END
    delimiter ;
    Bonjour Nekfeu,

    On ne peut ignorer une opération en cours via un trigger.
    La seule façon d'inhiber l'opération (via un trigger) est de provoquer une erreur lors de l'insertion.

    2 méthodes :
    - facile : simpl(ist)e et inélégante, elle ne peut s'appliquer que si la clé primaire de la table en insertion n'a pas l'attribut auto-incrément : -> SET NEW.[PrimaryKey] = NULL; /* sur le Before insert */
    - un peu plus complexe : générer une exception dans le trigger qui provoquera l'erreur via une instruction SIGNAL

  4. #4
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2016
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 27
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2016
    Messages : 3
    Points : 1
    Points
    1
    Par défaut
    Merci à vous deux pour vos réponses.



    Cependant je reste bloqué et je ne peux malheureusement pas utiliser la méthode simple car ma clé primaire est en auto-incrémente. J'ai essayé le EXEPTION comme si dessous mais je reçois une erreur de syntaxe. Je pense que c'est du au fait que je suis sous Mysql et non sous oracle.

    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
     
    DECLARE
    date_invalid EXCEPTION;
    BEGIN
     
    IF (select Date_form from formation, session 
        where formation.num_formation=session.num_formation
        and DATE_ADD(Date_form, INTERVAL 3 MONTH) < NEW.date_session)
    THEN
    RAISE date_invalid;
    END IF;
     
    EXCEPTION
       WHEN date_invalid THEN
    signal sqlstate '45000' set message_text = 'La date de la séance doit avoir lieu 3 mois après la date de création de la formation!';
    END
    J'ai également testé la même méthode que la première fois mais en remplaçant le DELETE par SIGNAL comme si dessous et je reçois cette fois lors de mes tests le message d'erreur : "#1242 - Subquery returns more than 1 row"

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    BEGIN
    IF (select Date_form from formation, session 
        where formation.num_formation=session.num_formation
    	and DATE_ADD(Date_form, INTERVAL 3 MONTH) > NEW.date_session)
    THEN    
    signal sqlstate '45000' set message_text = 'La date de la séance doit avoir lieu 3 mois après la date de création de la formation!';
    END IF;
    END
    Je commence à désespérer surtout que je dois présenter ce trigger pour mon projet de BTS dans 2 jours.

  5. #5
    Membre émérite Avatar de vttman
    Homme Profil pro
    Développeur "couteau mosellan"
    Inscrit en
    Décembre 2002
    Messages
    1 140
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur "couteau mosellan"
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2002
    Messages : 1 140
    Points : 2 286
    Points
    2 286
    Par défaut
    Vérifier les triggers créés
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT * FROM INFORMATION_SCHEMA.TRIGGERS
    Détruire ceux qui existeraient
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    DROP TRIGGER IF EXISTS Nom_trigger
    Puis Essayer ceci

    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
    DECLARE
    date_invalid EXCEPTION;
    BEGIN
     
    IF (select count(Date_form) from formation, session 
        where formation.num_formation=session.num_formation
        and DATE_ADD(Date_form, INTERVAL 3 MONTH) < NEW.date_session)
    THEN
    RAISE date_invalid;
    END IF;
     
    EXCEPTION
       WHEN date_invalid THEN
    signal sqlstate '45000' set message_text = 'La date de la séance doit avoir lieu 3 mois après la date de création de la formation!';
    END
    Emérite, émérite je ne pense pas ... plutôt dans le développement depuis FORT FORT longtemps, c'est mon job, ça oui
    A part ça ... Il ne pleut jamais en Moselle !

  6. #6
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2016
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 27
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2016
    Messages : 3
    Points : 1
    Points
    1
    Par défaut
    J'ai suivi les indications à la lettre que tu m'as donné et je reçois toujours le message d'erreur :
    "#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 ".

    Je me suis renseigné d'avantage sur la fonction EXCEPTION et j'ai pu constater qu'elle fonctionnait que sur PL SQL et pas sur MYSQL d'où cette erreur de syntaxe.

    Existe-t-il l'équivalent de cette fonction sous mysql ?

  7. #7
    Membre émérite Avatar de vttman
    Homme Profil pro
    Développeur "couteau mosellan"
    Inscrit en
    Décembre 2002
    Messages
    1 140
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur "couteau mosellan"
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2002
    Messages : 1 140
    Points : 2 286
    Points
    2 286
    Par défaut
    Sous Mysql version 5.7.11
    chez moi ce code fonctionne par exemple

    ex:
    Création d'une table x avec 2 champs x1 et x2
    Nom : Capture2.JPG
Affichages : 666
Taille : 19,7 Ko


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    DROP TRIGGER IF EXISTS chk_ok;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    SELECT * FROM INFORMATION_SCHEMA.TRIGGERS;
    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
     
    DELIMITER $$
     
    CREATE TRIGGER chk_OK  
    BEFORE INSERT ON x  
    FOR EACH ROW  
    BEGIN  
      DECLARE dummy INT;
      IF (select count(x1) from x 
            where x.x1 = new.x1)
    THEN  
      signal sqlstate '45000' set message_text = 'Enregistrement deja existant !';
    END IF;
    END $$
    delete from x;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    insert into `x` (x1,x2) values ('OK1',1);
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    insert into `x` (x1,x2) values ('OK1',1);
    Nom : Capture.JPG
Affichages : 659
Taille : 15,2 Ko
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    insert into `x` (x1,x2) values ('OK2',1);
    Nom : Capture1.JPG
Affichages : 651
Taille : 15,9 Ko
    Emérite, émérite je ne pense pas ... plutôt dans le développement depuis FORT FORT longtemps, c'est mon job, ça oui
    A part ça ... Il ne pleut jamais en Moselle !

  8. #8
    Membre émérite Avatar de vttman
    Homme Profil pro
    Développeur "couteau mosellan"
    Inscrit en
    Décembre 2002
    Messages
    1 140
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur "couteau mosellan"
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2002
    Messages : 1 140
    Points : 2 286
    Points
    2 286
    Par défaut
    Et puis, entre nous, la prochaine fois si tu veux avoir des réponses très rapides
    Un "export" du problème rencontré et comme ça sans doute + de réponses assurées

    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
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
     
    -- phpMyAdmin SQL Dump
    -- version 4.5.5.1
    -- http://www.phpmyadmin.net
    --
    -- Client :  127.0.0.1
    -- Généré le :  Dim 20 Novembre 2016 à 07:42
    -- Version du serveur :  5.7.11
    -- Version de PHP :  5.6.19
     
    SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
    SET time_zone = "+00:00";
     
     
    /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
    /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
    /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
    /*!40101 SET NAMES utf8mb4 */;
     
    --
    -- Base de données :  `hell`
    --
     
    -- --------------------------------------------------------
     
    --
    -- Structure de la table `x`
    --
     
    CREATE TABLE `x` (
      `x1` varchar(15) NOT NULL,
      `x2` int(11) NOT NULL
    ) ENGINE=MyISAM DEFAULT CHARSET=latin1;
     
    --
    -- Contenu de la table `x`
    --
     
    INSERT INTO `x` (`x1`, `x2`) VALUES
    ('OK1', 1),
    ('OK2', 1);
     
    --
    -- Déclencheurs `x`
    --
    DELIMITER $$
    CREATE TRIGGER `chk_OK` BEFORE INSERT ON `x` FOR EACH ROW BEGIN  
      DECLARE dummy INT;
      IF (select count(x1) from x 
            where x.x1 = new.x1)
    THEN  
      signal sqlstate '45000' set message_text = 'Enregistrement deja existant !';
    END IF;
    END
    $$
    DELIMITER ;
     
    /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
    /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
    /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
    Emérite, émérite je ne pense pas ... plutôt dans le développement depuis FORT FORT longtemps, c'est mon job, ça oui
    A part ça ... Il ne pleut jamais en Moselle !

Discussions similaires

  1. Erreur SQL 1442, Requete UPDATE ne marche pas
    Par noxa02 dans le forum SQL Procédural
    Réponses: 4
    Dernier message: 20/03/2012, 01h06
  2. Trigger on insert ne fonctionne pas
    Par Stessy dans le forum PL/SQL
    Réponses: 18
    Dernier message: 18/01/2008, 21h51
  3. * du SQL pour un INT ? % ne fonctionne pas...
    Par Allen dans le forum Requêtes et SQL.
    Réponses: 5
    Dernier message: 26/04/2006, 12h23
  4. [SQL] Requête à jointure qui ne fonctionne pas
    Par Bensor dans le forum Langage SQL
    Réponses: 2
    Dernier message: 09/12/2004, 17h10

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