Procédure stockée

Résolu
Utilisateur anonyme -  
 Utilisateur anonyme -
Bonjour

Je suis en train de regarder comment faire une procédure stockée sur MySQL...

Contexte :

table md_visites_jour qui contient 4 champs INT : jour,mois,annee,nombre

En fait à chaque visite d'un membre sur mon site je veux incrémenter la variable membre, et mon plus gros problème se situe au niveau de la création de l'enregistrement pour chaque jour. En effet, le premier visiteur du jour, il n'y a pas encore l'entrée du jour dans cette table, il faut donc qu'elle soit crée pour que les visites puissent être comptabilisée

voilà ce que j'ai fais pour l'instant (qui marche pas du tout mais qui compile ^^)

CREATE PROCEDURE incrementVisit(IN pday INT(10),IN pmonth INT(10),IN pyear INT(10))
BEGIN
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000', SQLEXCEPTION 
BEGIN
INSERT INTO md_visites_jour SET nombre=1, jour=pday, mois=pmonth, annee=pyear;
END;
UPDATE md_visites_jour SET nombre=nombre+1 WHERE jour=pday AND mois=pmonth AND annee=pyear;
END|


la requête s'exécute bien (sans erreur), mais l'enregistrement lié au jour n'es pas créé
si l'enregistrement pour le jour existe déjà, là aucun problème le champ nombre est bien incrémenté

sinon n'y a t il pas la possibilité que mysql recup lui même quel jour on est plutôt que de lui passer en paramètre ?

merci

6 réponses

  1. fiu
     
    ahhh ok ok ok ok d'accord !

    sache qu'un update qui met 0 (ZERO) ligne à jour ne déclenche pas d'erreur !

    donc si ta gestion d'erreur est en place pour gérer le fait qu'aucune ligne n'est mise à jour par ton update, elle ne servira jamais à ça (elle risque simplement de te masquer d'autres erreurs).

    si tu as besoin de savoir combien de lignes ont été impactées par la dernière requête, tu dois avoir un moyen simple de le déterminer (je te laisser chercher pour MySQL, en oracle c'est sql%ROWCOUNT)
    ...et dans ta procédure, si tu découvres que 0 ligne a été mise à jour par ton update, c'est alors le moment de balancer ton insert

    pour ma part, je pense que cette fonction (ou pseudo-colonne ou attribut) existe car, depuis un interpréteur MySQL, le nombre de lignes impactées par la dernière requête est toujours annoncé après le résultat.
    1
  2. fiu
     
    Salut

    Je suis pas très doué en MySQL (et donc encore moins dans ses procédures stockées).
    Ce qui me chagrine, c'est ce INSERT INTO table SET colonne=expression.
    Est-ce du SQL valide pour MySQL ?

    pour ma part, j'aurais plutot fait
    -- 1. récupérer s'il existe déjà un compteur pour la journée
    SELECT count(1)
      INTO compteur
      FROM md_visites_jour
      WHERE jour=pday
      AND mois=pmonth
      AND annee=pyear;
    -- 2. si oui alors update si non lors insert
    IF compteur > 0 THEN
      UPDATE md_visites_jour
        SET nombre = nombre + 1
        WHERE jour=pday
        AND mois=pmonth
        AND annee=pyear;
    ELSE
      INSERT INTO md_visites_jour
        VALUES(1, pday, pmonth, pyear)
    END IF

    il te reste maintenant à adapter ça à MySQL car
    * je sais pas si le select into est valide
    * je sais pas si le if est valide
    0
  3. Utilisateur anonyme
     
    De une j'ai dis que la reqête s'exécutait,
    de 2 pourquoi ca serai pas valide ? tu n'a jamais fait un INSERT en sql ? XD
    0
  4. fiu
     
    euh... en MySQL jamais :-)

    mais tu as raison, ne connaissant pas MySQL je n'aurais ptetre pas du chercher à filer un coup de main: "mal savoir est pire qu'ignorer"

    Ce qui me laissait penser à une erreur, c'est le DECLARE CONTINUE HANDLER ... que je voyais bien comme un gestionnaire d'exception qui te cache une erreur d'exécution (que je croyais être INSERT INTO... SET... car je connaissais pas cette syntaxe)
    0
  5. Vous n’avez pas trouvé la réponse que vous recherchez ?

    Posez votre question
  6. Utilisateur anonyme
     
    ba je me suis basé sur le siteduzero

    le declare continue handler c'est la gestion d'erreur lnormalement, et en fait je voulais exploiter ca, car s'il arrive pas à mettre à jour un enregistrement qui existe pas logiquement une erreur est levée, et donc moi je veux la récupérer pour faire l'insertion (au lieu de l'update)

    car dans ta solution dans tous les cas 2 requetes sont éxécutée, dans ma solution, dans 99% des cas, une seule requete sera executé, il n'y aura qu'une seule fois par jour où 2 requete seront executées

    tout ceci dans un but d'optimisation maximale ^^

    enfin c'est quand même sympa d'essayer de m'aider ;)
    0
  7. Utilisateur anonyme
     
    ok merci, je vais regarder du coté du rowcount, il me semble avoir vu une fonction php-mysql en rapport avec ca donc c'est que ca existe ^^

    EDIT voilà réussi \o/
    CREATE PROCEDURE incrementVisit(IN pday INT(10),IN pmonth INT(10),IN pyear INT(10)) 
    BEGIN 
    DECLARE rowcount INT; 
    UPDATE md_visites_jour SET nombre=nombre+1 WHERE jour=pday AND mois=pmonth AND annee=pyear; 
    SELECT ROW_COUNT() INTO rowcount; 
    IF rowcount= 0 THEN 
    INSERT INTO md_visites_jour SET nombre=1, jour=pday, mois=pmonth, annee=pyear; 
    END IF; 
    END|


    Prochaine étape réussir à trouver si mysql connais le joru qu'on est afin de supprimer les paramètres ^^

    EDIT2 voilà procédure stockée terminée ^^
    CREATE PROCEDURE incrementVisit()
    BEGIN
    	DECLARE rowcount INT;
            UPDATE md_visites_jour SET nombre=nombre+1 WHERE jour=DAY(NOW()) AND mois=MONTH(NOW()) AND annee=YEAR(NOW());
    	SELECT ROW_COUNT() INTO rowcount;
    	IF rowcount= 0 THEN
    		INSERT INTO md_visites_jour SET nombre=1, jour=DAY(NOW()), mois=MONTH(NOW()), annee=YEAR(NOW());
    	END IF;
    END|


    Lapinkiller, Développeur web & Java.
    "Ne prend pas ta vie à 2 mains, gardes en une de libre pour te rattraper au cas où tu tomberais..." (Lapinkiller)
    0