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 :

Simple procédure pour insert une ligne ou update un champ [MySQL-5.1]


Sujet :

SQL Procédural MySQL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé

    Inscrit en
    Janvier 2006
    Messages
    188
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 188
    Par défaut Simple procédure pour insert une ligne ou update un champ
    Bonjour,
    je suis nouveau sous mysql et j'essaye de creer une pocedure assez simple.
    Elle a ete acceptee mais le comportement est plutot bizarre.

    Voici la table:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    create table down(
        user    int            not null,
        month varchar(7)  not null,
        size     int
    );
    alter table down add constraint cUser_fk
        foreign key(user) references auth(id);
     
    create unique index iDown_x1 on down(user);
    create unique index iDown_x2 on down(user,month);

    Ma proc, add_user_size(in user_id int, in month varchar(7), in size int) doit:
    - creer une entree si il n'y a pas deja un couple (user_id, month)
    - ajouter la size si il y a deja une entree

    Voici le code
    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
     
    DELIMITER $$
     
    create procedure add_user_size(
            in     user_id int,
            in     month   varchar(7),
            in     size    int
    )
    begin
        declare month_exist int;
        declare c_size      int;
     
        select
            count(*)
        into
            month_exist
        from
            down
        where
            user=user_id
        and month=month;
     
        if (month_exist > 0) then
            select
                size
            into
                c_size
            from
                down
            where
                user=user_id
            and month=month;
     
            set c_size = c_size + size;
     
            update
                down
            set
                size=c_size
            where
                user=user_id
            and month=month;
        else
            insert into down (
                    user,
                    month,
                    size
            ) values (
                user_id,
                month,
                size
            );
        end if;
    end $$
     
    DELIMITER ;
    Lorsque je fais un premier call:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    call add_user_size(3, "2013.10", 200);
    Une ligne est cree.
    Par contre qu'en ensuite je la reutilise avec:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    call add_user_size(3, "2013.10", 300);
    La size passe a 600 au lieu de 500... oO

    Si je continue, j'ai encore un comportement etrange.

    - Quelqu'un peu m'expliquer ce qui ne va pas?

    - Autre question, suis je oblige de passer par une premiere requete pour avoir le count(*) ou y a't'il un moyen de faire directement la requete pour avoir la size et ensuite tester si le select a eu des reponses?

    - Derniere question: comment puis je passer le parametre size en inout afin de modifier cette variable (au lieu de c_size) et la retourner en output. Dois je faire un return size a la fin?

    Merci d'avance.

  2. #2
    Membre confirmé

    Inscrit en
    Janvier 2006
    Messages
    188
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 188
    Par défaut
    bon j'ai une version qui marche:
    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
     
    DELIMITER $$
     
    create procedure add_user_size(
            in  p_user_id int,
            in  p_month   varchar(7),
            in  p_size    int
    )
    begin
        declare month_exist int;
     
        select
            count(*)
        into
            month_exist
        from
            down
        where
            user=p_user_id
        and month=p_month;
     
        if (month_exist > 0) then
            update
                down
            set
                size=size+p_size
            where
                user=p_user_id
            and month=p_month;
        else
            insert into down (
                    user,
                    month,
                    size
            ) values (
                p_user_id,
                p_month,
                p_size
            );
        end if;
    end $$
     
    DELIMITER ;
    mais j'aimerai bien comprendre le probleme de ma fonction du dessus.
    car idealement j'aimerai retourner la nouvelle size et donc garder une approche avec un select de la size originale dans une variable temporaire...

  3. #3
    Membre confirmé

    Inscrit en
    Janvier 2006
    Messages
    188
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 188
    Par défaut
    bon c'est bon...
    il semble qu'il faille utiliser une variable et on ne peut pas avoir le resultat en return comme un simple select... pas top...
    au final voici ma proc:
    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
     
    create procedure add_user_size(
            in  p_user_id int,
            in  p_month   varchar(7),
            inout  p_size    int
    )
    begin
        declare month_exist int;
        declare c_size      int;
     
        select
            count(*)
        into
            month_exist
        from
            down
        where
            user=p_user_id
        and month=p_month;
     
        if (month_exist > 0) then
            select
                size
            into
                c_size
            from
                down
            where
                user=p_user_id
            and month=p_month;
     
            set p_size = p_size + c_size;
     
            update
                down
            set
                size=p_size
            where
                user=p_user_id
            and month=p_month;
        else
            insert into down (
                    user,
                    month,
                    size
            ) values (
                p_user_id,
                p_month,
                p_size
            );
        end if;
    end $$
    DELIMITER ;

    L'utilisation via mysql:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    mysql> set @size:=500;
    Query OK, 0 rows affected (0.00 sec)
     
    mysql> call add_user_size(3,"2013.09",@size);
    ou via java histoire de recuperer le resultat:
    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
     
    	public int add_user_size(){
    		int new_size=-1;
    		try {
    			CallableStatement cs = con.prepareCall("{call add_user_size(?,?,?)}");
    			cs.setInt(1, 3);
    			cs.setString(2, "2013.11");
    			cs.setInt(3, 300);
    			cs.registerOutParameter(3, Types.INTEGER);
     
    			cs.execute();
     
    			new_size  = cs.getInt(3);
    		} catch (SQLException ex){
    			ex.printStackTrace();
    		}
     
    		System.out.println("add_user_size(3,'2013.11',300) returns: "+new_size);
    		return new_size;
    	}

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

Discussions similaires

  1. Comment faire pour ajouter une ligne seulement !
    Par Fredri dans le forum Access
    Réponses: 1
    Dernier message: 26/12/2005, 11h44
  2. Réponses: 4
    Dernier message: 24/09/2005, 09h52
  3. Comment faire pour modifier une ligne dans une DBGrid?
    Par Nico62 dans le forum C++Builder
    Réponses: 6
    Dernier message: 29/03/2005, 12h24
  4. Réponses: 2
    Dernier message: 08/08/2003, 17h30

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