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 :

Trigger pour éviter les valeurs <= 0


Sujet :

SQL Procédural MySQL

  1. #1
    Membre actif

    Inscrit en
    Mars 2002
    Messages
    83
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 83
    Par défaut Trigger pour éviter les valeurs <= 0
    Bonjour.

    Je viens de découvrir les triggers et désirant apprendre, j'essai dans créer un afin de prévenir l'insertion de valeurs négatives ou 0 dans une table en utilisant un trigger.

    table1 :
    col1 : Integer
    col2 : Varchar(32)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    INSERT INTO table1 (col1, col2) VALUES (1, 'azerty');
    Dans ce cas c'est bon : On insert.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    INSERT INTO table1 (col1, col2) VALUES (0, 'azerty');
    Ce n'est pas bon : On insert pas parceque col1 <=0.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    UPDATE table1 SET col1 = -1, col2 = 'azerty' WHERE col1 = '1' AND col2 = 'azerty'
    Dans ce cas : On supprime l'enregistrement parceque col1 <= 0


    Dans le cas de l'update je pense qu'il y aura un soucis de vérouillage de la table parceque j'ai ce genre de problème avec un trigger after update sur la table1.

    Merci.

  2. #2
    Membre éprouvé
    Avatar de berceker united
    Profil pro
    SQL
    Inscrit en
    Février 2005
    Messages
    3 510
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : SQL
    Secteur : Finance

    Informations forums :
    Inscription : Février 2005
    Messages : 3 510
    Par défaut
    Tu n'as pas besoin de faire un trigger pour cela. Il suffit de rendre ton champ UNSIGNED. Ainsi, seul les valeurs >=0 peuventre être inséré.
    Mais admettons :
    Il y a un autre problème. Tu modifies l'information après l'insertion.
    Il suffit d'executer le trigger en BEFOR UPDATE ou BEFOR INSERT. Tu contrôles avant qu'elle soit enregistré. Ainsi tu n'as pas à retourner dans la table pour modifier la données. Je rajouterais en plus que c'est pas trop possible.

  3. #3
    Membre actif

    Inscrit en
    Mars 2002
    Messages
    83
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 83
    Par défaut
    Merci.

    Je fais ça pour apprendre à utiliser les triggers (c'est un exercice) parceque là je peine un peu. Je n'arrive pas à lui dire de rien faire, ou de détruire l'enregistrement dans le cas ou les conditions ne sont pas remplies.

  4. #4
    Membre éprouvé
    Avatar de berceker united
    Profil pro
    SQL
    Inscrit en
    Février 2005
    Messages
    3 510
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : SQL
    Secteur : Finance

    Informations forums :
    Inscription : Février 2005
    Messages : 3 510
    Par défaut
    Tu veux refuser l'enregistrement ou reformater la données mal formé ?

  5. #5
    Membre actif

    Inscrit en
    Mars 2002
    Messages
    83
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 83
    Par défaut
    Je dirais les deux.

    1 - Ne pas enregistrer si col1<=0
    exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    INSERT INTO table1 (col1, col2) VALUES (0, 'azerty');
    Dans un second temps :

    2 - Supprimer automatiquement un enregistrement quand la valeur de col1<=0
    exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    UPDATE table1 SET col1 = -1, col2 = 'azerty' WHERE col1 = '1' AND col2 = 'azerty'

  6. #6
    Membre éprouvé
    Avatar de berceker united
    Profil pro
    SQL
    Inscrit en
    Février 2005
    Messages
    3 510
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : SQL
    Secteur : Finance

    Informations forums :
    Inscription : Février 2005
    Messages : 3 510
    Par défaut
    Tu ne peux pas empecher une opération d'écriture si elle a été lancé. Le trigger n'est pas tellement fait pour cela. Il faut dans ce cas là, il est préférable d'utiliser des procedures stockés.

  7. #7
    Rédacteur/Modérateur

    Avatar de Antoun
    Homme Profil pro
    Architecte décisionnel
    Inscrit en
    Octobre 2006
    Messages
    6 288
    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 288
    Par défaut
    Cas 1/ le trigger ne peut EXPLICITEMENT refuser l'action. Par contre il peut la faire échouer, par ex. :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    CREATE TRIGGER table1_BI BEFORE INSERT ON table1
    FOR EACH ROW
    IF new.col1 <= 0 THEN SET new.col1 = 'alpha' END IF ;
    Cas 2/ on ne peut pas utiliser la même technique parce que si le trigger échoue, l'UPDATE échouera aussi, et la ligne subsistera avec son ancienne valeur. Si tu as une ID sur la ligne, tu peux faire un AFTER UPDATE :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    CREATE TRIGGER table1_AU AFTER UPDATE ON table1
    FOR EACH ROW
    IF new.col1 <= 0 THEN DELETE FROM table1 WHERE table1.ID = new.ID ;

  8. #8
    Membre actif

    Inscrit en
    Mars 2002
    Messages
    83
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 83
    Par défaut
    Merci pour l'information.

    Là ça marche au niveau syntaxe, mais pas en fonctionnement.

    MySQL : 5.0.41

    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
    DROP TABLE IF EXISTS `table1`;
    CREATE TABLE `table1` (
    `col1` INT( 4 ) NOT NULL ,
    `col2` VARCHAR( 32 ) NOT NULL
    ) ENGINE = innodb;
     
     
    delimiter //
    DROP TRIGGER IF EXISTS trig1//
    CREATE TRIGGER trig1
    BEFORE INSERT ON table1
    FOR EACH ROW
    BEGIN  
        IF new.col1 <= 0 THEN
            SET new.col1 = 'alpha';
        END IF;
    END;//
    delimiter ;
     
     
    INSERT INTO `table1` (`col1`,`col2`)
    VALUES	('1','a'),
    				('2','b'),
    				('0','*'),
    				('-1','*');
     
    SELECT * FROM `table1`;
    Résultat :
    +------+------+
    | col1 | col2 |
    +------+------+
    | 1 | a |
    | 2 | b |
    | 0 | * |
    | 0 | * |
    +------+------+

  9. #9
    Membre éprouvé
    Avatar de berceker united
    Profil pro
    SQL
    Inscrit en
    Février 2005
    Messages
    3 510
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : SQL
    Secteur : Finance

    Informations forums :
    Inscription : Février 2005
    Messages : 3 510
    Par défaut
    Normal car tu lui donne une chaine de caractère. Donc il te place un zero. Par contre, heureusement que Mysql est intelligent car en placant un zero il aurait pu tourner en rond.
    Donc ce test montre bien que le trigger s'execute qu'une seul fois.

  10. #10
    Membre actif

    Inscrit en
    Mars 2002
    Messages
    83
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 83
    Par défaut
    Ok.

    Le Trigger dans ce cas remplace la valeur négative par une chaine de caractère, et il me semblait que le transtypage n'était pas automatique.

    Pour palier au problème je génère une erreur en appelant une procedure qui n'existe pas

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    delimiter //
    DROP TRIGGER IF EXISTS trig1//
    CREATE TRIGGER trig1
    BEFORE INSERT ON table1
    FOR EACH ROW
    BEGIN  
        IF new.col1 <= 0 THEN
    	CALL NOM_ERREUR();
        END IF;
    END;//
    delimiter ;
    INSERT INTO `table1` (`col1` ,`col2`)
    VALUES ('-1', '-1')

    #1305 - PROCEDURE jawxshop.NOM_ERREUR does not exist




    Pour ce qui est de l'UPDATE :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    delimiter //
    DROP TRIGGER IF EXISTS trig2//
    CREATE TRIGGER trig2
    AFTER UPDATE ON table1
    FOR EACH ROW
    BEGIN  
        IF new.col1 <= 0 THEN
    	DELETE FROM table1 WHERE table1.col1 = new.col1 ;
        END IF;
    END;//
    delimiter ;
    #1442 - Can't update table 'table1' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
    Il doit y avoir un soucis de concurrence d'accès à la table. étant donné qu'elle est vérouillée par la procédure d'update, il n'est pas possible d'effectuer d'autres opérations.

  11. #11
    Membre éprouvé
    Avatar de berceker united
    Profil pro
    SQL
    Inscrit en
    Février 2005
    Messages
    3 510
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : SQL
    Secteur : Finance

    Informations forums :
    Inscription : Février 2005
    Messages : 3 510
    Par défaut
    Il y a un cas ou j'ai réussi à écrire dans une table concurrent. Je me rappelle pas trop comment j'ai réussi à m'en sortir. Bref, L'idée de provoquer une erreur n'est pas trop mal mais c'est une technique de cabot

    J'ai rencontré le même problème que toi. J'ai résolu le problème en gérant toute les entrées de la base de données en passante par les procédures stocké. En gros, il n'est pas possible de faire des enregistrements directement sur une table. Il faut obligatoirement passer par une procédure stocké. Ainsi, tu peux contrôler les entrés.

  12. #12
    Membre actif

    Inscrit en
    Mars 2002
    Messages
    83
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 83
    Par défaut
    Pas facile. au moins j'aurais appris des trucs sur les triggers. Maintenant je vais donc m'interresser aux procédures. En tout cas merci pour l'aide .

  13. #13
    Membre éprouvé
    Avatar de berceker united
    Profil pro
    SQL
    Inscrit en
    Février 2005
    Messages
    3 510
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : SQL
    Secteur : Finance

    Informations forums :
    Inscription : Février 2005
    Messages : 3 510
    Par défaut
    Il est prévus que je fasse un article sur les Procédures stocké, Fonctions et Triggers.
    Il y a des petites choses à savoir qui n'est pas forcément dit dans le documentation officiel.

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 28/06/2006, 08h53
  2. Problème pour classer les valeurs d'un champ
    Par AjJi dans le forum Access
    Réponses: 11
    Dernier message: 06/04/2006, 09h19
  3. requete pour compter les valeurs ds une colonne
    Par smariteau dans le forum Requêtes
    Réponses: 2
    Dernier message: 10/02/2006, 17h37
  4. Réponses: 2
    Dernier message: 13/11/2005, 18h03

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