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 :

Procedure stockée et PHP


Sujet :

SQL Procédural MySQL

  1. #1
    Membre éclairé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juin 2014
    Messages
    744
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Juin 2014
    Messages : 744
    Par défaut Procedure stockée et PHP
    Bonjour.
    J'essaie de faire ma première procédure stockée et d'appeler le résultat côté serveur php et IHM et je me heurte aux 2 premières difficultés.
    chercher des résultat sur un mois/année donnés : le problème est notamment que les dates sont au format Date dans ma bdd et je des résultats par an et par mois et uniquement pour un mois donné.
    Comment récupérer ce résultat côté IHM ?
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    DELIMITER |
     
    CREATE PROCEDURE somme_mensuelle (IN an INT, IN mois INT)
    BEGIN
        SELECT date, SUM(kms)
        FROM sorties
        GROUP BY an, mois
        ORDER BY an, mois
    END |
     
    DELIMITER ;

    Est ce que je dois seulement mettre une requête
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    $ma_requete="CALL somme_mensuelle (2015, 3);";
     
    $resultat=mysqli_query($db_link,$ma_requete)
    pour avoir la somme du mois de mars 2015 ?

  2. #2
    Membre prolifique Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 868
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 868
    Par défaut
    Salut 69pierre.

    Commençons par ta requête.
    Citation Envoyé par 69pierre
    chercher des résultat sur un mois/année donnés
    Tu cherches à extraire d'une date données, d'une part l'année et d'autre part le mois, afin de faire une tri Est-ce bien cela ?

    La réponse se trouve dans ce lien : https://dev.mysql.com/doc/refman/5.7...functions.html

    Extraire séparément l'année et le mois, puisque dans ton exemple, tu désires faire un regroupement.
    --> month()
    --> year()

    Passons à ta procédure stockée.
    Je n'ai pas bien compris ce que tu veux faire avec ta procédure stockée.
    C'est juste afficher la liste de ta sélection ? Ou bien récupérer le résultat ?

    Voici un exemple :
    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
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    --------------
    SET AUTOCOMMIT = 0
    --------------
     
    --------------
    START TRANSACTION
    --------------
     
    --------------
    DROP DATABASE IF EXISTS `base`
    --------------
     
    --------------
    CREATE DATABASE `base`
        DEFAULT CHARACTER SET `latin1`
        DEFAULT COLLATE       `latin1_general_ci`
    --------------
     
    --------------
    DROP TABLE IF EXISTS `test`
    --------------
     
    --------------
    CREATE TABLE `test` (
      `id`   int  NOT NULL AUTO_INCREMENT PRIMARY KEY,
      `date` date NOT NULL,
      `kms`  int  NOT NULL
    ) ENGINE=InnoDB
      DEFAULT CHARSET=`latin1` COLLATE=`latin1_general_ci`
      ROW_FORMAT=COMPRESSED
    --------------
     
    --------------
    insert into test (`date`, `kms`) values
    ('2015-12-01', 200), ('2015-11-01', 150), ('2015-11-17', 300), ('2015-10-17', 75), ('2015-10-23', 125)
    --------------
     
    --------------
    select * from test
    --------------
     
    +----+------------+-----+
    | id | date       | kms |
    +----+------------+-----+
    |  1 | 2015-12-01 | 200 |
    |  2 | 2015-11-01 | 150 |
    |  3 | 2015-11-17 | 300 |
    |  4 | 2015-10-17 |  75 |
    |  5 | 2015-10-23 | 125 |
    +----+------------+-----+
    --------------
    select year(date) as 'annee', month(date) as 'mois', sum(kms)
    from test
    group by annee, mois
    order by annee, mois
    --------------
     
    +-------+------+----------+
    | annee | mois | sum(kms) |
    +-------+------+----------+
    |  2015 |   10 |      200 |
    |  2015 |   11 |      450 |
    |  2015 |   12 |      200 |
    +-------+------+----------+
    --------------
    drop procedure `list`
    --------------
     
    ERROR 1305 (42000) at line 52: PROCEDURE base.list does not exist
    --------------
    create procedure list
    (
            IN  _annee  int,
            IN  _mois   int,
            out _kms    int
    )
    DETERMINISTIC
    NO SQL
    BEGIN
      select sum(kms) into _kms
      from test
      where year(date)  = _annee
      and   month(date) = _mois
      group by year(date), month(date)
      order by year(date), month(date);
    END
    --------------
     
    --------------
    set @kms := 0
    --------------
     
    --------------
    call list (2015, 11, @kms)
    --------------
     
    --------------
    select @kms as 'kms'
    --------------
     
    +------+
    | kms  |
    +------+
    |  450 |
    +------+
    --------------
    COMMIT
    --------------
     
    --------------
    SET AUTOCOMMIT = 1
    --------------
     
     
    Appuyez sur une touche pour continuer...
    C'est juste une première ébauche de ce que tu cherches à faire.
    Si tu veux quelque chose de plus précis, tu n'as qu'à formuler ta demande !

    @+

  3. #3
    Membre éclairé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juin 2014
    Messages
    744
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Juin 2014
    Messages : 744
    Par défaut
    Merci Artemus24.
    Citation Envoyé par Artemus24 Voir le message
    Salut 69pierre.
    Tu cherches à extraire d'une date données, d'une part l'année et d'autre part le mois, afin de faire une tri Est-ce bien cela ?
    Oui c'est bien cela.
    Citation Envoyé par Artemus24 Voir le message
    Passons à ta procédure stockée.
    Je n'ai pas bien compris ce que tu veux faire avec ta procédure stockée.
    C'est juste afficher la liste de ta sélection ? Ou bien récupérer le résultat ?
    Récupérer le résultat (la ou les sommes) et l'afficher avec php.

  4. #4
    Membre éclairé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juin 2014
    Messages
    744
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Juin 2014
    Messages : 744
    Par défaut
    Bonjour.
    Je ne comprends toujours pas comment récupérer dans mon php, les résultats issus de la procédure stockée.

    Dans un premier temps, à titre d'exemple et pour comprendre les procédures stockée, je souhaite que la procédure stockée soit écrite dans ma BDD, se déclenche au démarrage de mysql et que je puisse récupérer le résultat avec php (en procédural) pour l'afficher dans l'IHM.

    A terme, utiliser les procédures stockées et les lancer au démarrage de mysql pour qu'elle remplissent une table sera persistante au moins tous le temps de la session mysql.
    Ceci pour me permettre de faire des calculs un peu plus long à un autre moment que celui où les résultats sont demandés par l'utilisateur (/IHM).

    Merci de m'aider.
    Je ne sais pas par où commencer.

  5. #5
    Membre prolifique Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 868
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 868
    Par défaut
    Salut 69pierre.

    Je ne voie pas où se trouve la difficulté pour appeler une procédure stockée en php. Tu appelles ces trois lignes en php :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    --------------
    set @kms := 0
    --------------
     
    --------------
    call list (2015, 11, @kms)
    --------------
     
    --------------
    select @kms as 'kms'
    --------------
    Voici le même exemple en php :
    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
    61
    62
    63
    64
    65
    66
    67
    <!doctype html>
    <html>
    <head>
    <meta charset="ISO-8859-1" />
    <title>Exercice !</title>
     
    <link rel="stylesheet" type="text/css" href="../Styles.css">
    </head>
     
    <body>
    <h1>Exemple d'utilisation de MySql version PDO !</h1>
    <pre>
    <?php
    /*==================================*/
    /*     Ouverture de la connexion    */
    /*==================================*/
     
    /*-----------------------------------------------------*/
    /* Informations pour la connexion à la base de données */
    /*-----------------------------------------------------*/
     
    $nom_du_serveur  = "mysql:host=localhost;dbname=base";
    $nom_utilisateur = "base";
    $mot_de_passe    = "base";
     
    $options         = array(
    	PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES latin1",
    	PDO::ATTR_CASE               => PDO::CASE_LOWER,
    	PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION
    );
     
    /*----------------------*/
    /* Connexion au Serveur */
    /*----------------------*/
     
    try {
    	$link = new PDO($nom_du_serveur, $nom_utilisateur, $mot_de_passe, $options);
    }
    catch (Exception $e)
    {
    	echo "Connection à MySql impossible : ", $e->getMessage();
    	die();
    }
     
    /*=============================================*/
    /*                                             */
    /*=============================================*/
     
    try {$sql=$link->query("set @kms := 0;");}              catch ( Exception $e ) {echo "Une erreur est survenue dans la requète 1 : ", $e->getMessage(); die();}
    try {$sql=$link->query("call list (2015, 11, @kms);");} catch ( Exception $e ) {echo "Une erreur est survenue dans la requète 2 : ", $e->getMessage(); die();}
    try {$sql=$link->query("select @kms as 'kms';");}       catch ( Exception $e ) {echo "Une erreur est survenue dans la requète 3 : ", $e->getMessage(); die();}
     
    $row = $sql->fetch(PDO::FETCH_ASSOC);
    echo $row['kms'];
     
    $sql->closecursor();
     
    /*----------------------------------*/
    /*     Fermeture de la connexion    */
    /*----------------------------------*/
     
    $link=null;
     
    ?>
    </pre>
    </body>
    </html>
    Pour ton autre question :
    Citation Envoyé par 69pierre
    utiliser les procédures stockées et les lancer au démarrage de mysql
    je ne sais pas faire cela !

    D'ailleurs, qu'est-ce que tu appelles au démarrage de mysql ?
    En principe, ton SGBD MySql n'est pas censé s'arrêter.

    Je pense que tu dois trouver un moyen en php, peut-être avec la crontab si tu es sous unix, pour déclencher un traitement qui va déclencher ton traitement.
    En windows, il faut programmer dans "gestion de l'ordinateur", puis dans "planificateur de tâches".

    @+

  6. #6
    Membre éclairé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juin 2014
    Messages
    744
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Juin 2014
    Messages : 744
    Par défaut
    Bonjour et merci du temps que tu me consacres.

    "au démarrage de mysql.." : oui, c'est nul excuse moi, je travaille sur une clé avec easyphp (avec un localhost de toutes façons) donc j'ai pris le cas particulier pour le cas général, j'ai oublié de lever la tête.

    Par contre, il doit être possible de lancer ces procédures de manière quotidienne à heure fixe.

    Je vais faire un essai avec ce que tu me donnes mais j'essaie de faire tout ça avec du php procédural, je risque d'être long.

    A bientôt.

  7. #7
    Membre éclairé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juin 2014
    Messages
    744
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Juin 2014
    Messages : 744
    Par défaut
    Je rame.
    Je travaille avec adminer ou phpmyadmin.
    Dans adminer lorsque je veux créer une procédure stockée, on me demande le nom (lis), les paramètres (annee, _mois et _kms) puis le code :
    Code sql : 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
     
    DROP TABLE IF EXISTS `test`
     
     
     
    CREATE TABLE `test` (
      `id`   int  NOT NULL AUTO_INCREMENT PRIMARY KEY,
      `date` date NOT NULL,
      `kms`  int  NOT NULL
    ) ENGINE=InnoDB
      DEFAULT CHARSET=`latin1` COLLATE=`latin1_general_ci`
      ROW_FORMAT=COMPRESSED
     
    insert into test (`date`, `kms`) values
    ('2015-12-01', 200), ('2015-11-01', 150), ('2015-11-17', 300), ('2015-10-17', 75), ('2015-10-23', 125)
    -
     
     
    BEGIN
      select sum(kms) into _kms
      from test
      where year(date)  = _annee
      and   month(date) = _mois
      group by year(date), month(date)
      order by year(date), month(date);
    END
     
     
    set @kms := 0
     
     
    call list (2015, 11, @kms)
     
    select @kms as 'kms'
    J'ai des erreurs.

    J'ai revue ma copie.
    Dans un premier temps, je souhaite utiliser le code que tu m'as donné. C'est à dire :
    Créer la procédure list dans la BDD MA_BDD
    Puis ajouter les trois triggers pour qu'elle s'éxcute lors d'un CREATE, UPDATE ou DELETE
    Enfin faire via php un SELECT quelque chose qui stockera les valeurs @kms correspondants aux sommes mensuelles, faire dans la procédure une seconde table id (autoincrement), annee, mois, kms

    Je n'y arrive pas.

    Le but final étant de récupérer non pas les valeurs ('2015-12-01', 200), ('2015-11-01', 150), ('2015-11-17', 300), ('2015-10-17', 75), ('2015-10-23', 125) mais celles présentes dans ma bdd dans la tables sortie.

    Faute d'avoir réussi ce que je voulais faire, j'espère au moins avoir expliqué clairement mon objectif.

  8. #8
    Membre prolifique Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 868
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 868
    Par défaut
    Salut 69pierre.

    Citation Envoyé par 69pierre
    Je rame.
    Donc tu utilises une pagaie. Car si tu godilles ou gabares, tu utilises un aviron !

    Citation Envoyé par 69pierre
    J'ai des erreurs.
    Il manques des points-virgules à la fin de tes requêtes. A l'exécution, MySql n'affiche pas les points-virgules.
    Je vais te donner le source ainsi que le résultat de l'exécution.

    Citation Envoyé par 69pierre
    Puis ajouter les trois triggers pour qu'elle s'éxcute lors d'un CREATE, UPDATE ou DELETE
    Si tu me donnes bout après bout ce que tu veux faire, cela va être assez difficile de bien faire les choses.

    Voici le source en mysql :
    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
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    SET AUTOCOMMIT = 0;
    START TRANSACTION;
     
    -- ======================
    -- Base de Données `base`
    -- ======================
     
    DROP DATABASE IF EXISTS `base`;
     
    CREATE DATABASE `base`
        DEFAULT CHARACTER SET `latin1`
        DEFAULT COLLATE       `latin1_general_ci`;
     
    USE `base`;
     
    -- =====================
    -- Création Table `test`
    -- =====================
     
    DROP TABLE IF EXISTS `test`;
     
    CREATE TABLE `test` (
      `id`   int  NOT NULL AUTO_INCREMENT PRIMARY KEY,
      `date` date NOT NULL,
      `kms`  int  NOT NULL
    ) ENGINE=InnoDB 
      DEFAULT CHARSET=`latin1` COLLATE=`latin1_general_ci`
      ROW_FORMAT=COMPRESSED;
     
    -- ========================
    -- Création Table `grouper`
    -- ========================
     
    DROP TABLE IF EXISTS `grouper`;
     
    CREATE TABLE `grouper` (
      `an`   int  NOT NULL,
      `mois` int  NOT NULL,
      `kms`  int  NOT NULL,
      PRIMARY KEY (`an`,`mois`)
    ) ENGINE=InnoDB 
      DEFAULT CHARSET=`latin1` COLLATE=`latin1_general_ci`
      ROW_FORMAT=COMPRESSED;
     
    -- =========================
    -- Procédure stockée "trait"
    -- =========================
     
    drop procedure `trait`;
     
    delimiter $$ ;
    create procedure `trait`
    (
    	IN  _date date
    )
    DETERMINISTIC
    NO SQL
    BEGIN
      DECLARE _an   int DEFAULT 0;
      DECLARE _mois int DEFAULT 0;
      DECLARE _kms  int DEFAULT 0;
      DECLARE _bis  int DEFAULT NULL;
     
      set _an   = year (_date);
      set _mois = month(_date);
     
      select sum(kms) into _kms from test    where year(date) = _an and month(date) = _mois group by year(date), month(date);
      select     kms  into _bis from grouper where      an    = _an and       mois  = _mois;
     
      if (_bis IS NULL) then
           insert into `grouper` (`an`,`mois`,`kms`) values (_an, _mois, _kms);
      else update      `grouper` set kms = _kms where an = _an and mois = _mois;
      end if;
    END$$
    DELIMITER ;
     
    -- ========================
    -- Création Trigger "ajout"
    -- ========================
     
    DROP TRIGGER IF EXISTS `ajout`;
     
    DELIMITER $$
    CREATE TRIGGER `ajout`
    AFTER INSERT ON `test`
    FOR EACH ROW
    BEGIN
      call `trait` (new.date);
    END$$
    DELIMITER ;
     
    -- ========================
    -- Création Trigger "suppr"
    -- ========================
     
    DROP TRIGGER IF EXISTS `suppr`;
     
    DELIMITER $$
    CREATE TRIGGER `suppr`
    AFTER delete ON `test`
    FOR EACH ROW
    BEGIN
      call `trait` (old.date);
    END$$
    DELIMITER ;
     
    -- ========================
    -- Création Trigger "modif"
    -- ========================
     
    DROP TRIGGER IF EXISTS `modif`;
     
    DELIMITER $$
    CREATE TRIGGER `modif`
    AFTER update ON `test`
    FOR EACH ROW
    BEGIN
      call `trait` (old.date);
    END$$
    DELIMITER ;
     
    -- ===========
    -- Jeu d'essai
    -- ===========
     
    select * from test;
    select * from grouper;
     
    insert into test (`date`, `kms`) values
      ('2015-12-01', 200), ('2015-11-01', 150), ('2015-11-17', 300), ('2015-10-13', 75), ('2015-10-23', 125), ('2015-12-25', 50);
     
    select * from test;
    select * from grouper;
     
    delete from test where date = '2015-11-01';
     
    select * from test;
    select * from grouper;
     
    update test set kms = 25 where date = '2015-10-13';
     
    select * from test;
    select * from grouper;
     
    -- ===
    -- Fin
    -- ===
     
    COMMIT;
    SET AUTOCOMMIT = 1;
    Voici le résultat à l'exécution :
    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
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    --------------
    SET AUTOCOMMIT = 0
    --------------
     
    --------------
    START TRANSACTION
    --------------
     
    --------------
    DROP DATABASE IF EXISTS `base`
    --------------
     
    --------------
    CREATE DATABASE `base`
        DEFAULT CHARACTER SET `latin1`
        DEFAULT COLLATE       `latin1_general_ci`
    --------------
     
    --------------
    DROP TABLE IF EXISTS `test`
    --------------
     
    --------------
    CREATE TABLE `test` (
      `id`   int  NOT NULL AUTO_INCREMENT PRIMARY KEY,
      `date` date NOT NULL,
      `kms`  int  NOT NULL
    ) ENGINE=InnoDB
      DEFAULT CHARSET=`latin1` COLLATE=`latin1_general_ci`
      ROW_FORMAT=COMPRESSED
    --------------
     
    --------------
    DROP TABLE IF EXISTS `grouper`
    --------------
     
    --------------
    CREATE TABLE `grouper` (
      `an`   int  NOT NULL,
      `mois` int  NOT NULL,
      `kms`  int  NOT NULL,
      PRIMARY KEY (`an`,`mois`)
    ) ENGINE=InnoDB
      DEFAULT CHARSET=`latin1` COLLATE=`latin1_general_ci`
      ROW_FORMAT=COMPRESSED
    --------------
     
    --------------
    drop procedure `trait`
    --------------
     
    ERROR 1305 (42000) at line 49: PROCEDURE base.trait does not exist
    --------------
    create procedure `trait`
    (
            IN  _date date
    )
    DETERMINISTIC
    NO SQL
    BEGIN
      DECLARE _an   int DEFAULT 0;
      DECLARE _mois int DEFAULT 0;
      DECLARE _kms  int DEFAULT 0;
      DECLARE _bis  int DEFAULT NULL;
     
      set _an   = year (_date);
      set _mois = month(_date);
     
      select sum(kms) into _kms from test    where year(date) = _an and month(date) = _mois group by year(date), month(date);
      select     kms  into _bis from grouper where      an    = _an and       mois  = _mois;
     
      if (_bis IS NULL) then
           insert into `grouper` (`an`,`mois`,`kms`) values (_an, _mois, _kms);
      else update      `grouper` set kms = _kms where an = _an and mois = _mois;
      end if;
    END
    --------------
     
    --------------
    DROP TRIGGER IF EXISTS `ajout`
    --------------
     
    --------------
    CREATE TRIGGER `ajout`
    AFTER INSERT ON `test`
    FOR EACH ROW
    BEGIN
      call `trait` (new.date);
    END
    --------------
     
    --------------
    DROP TRIGGER IF EXISTS `suppr`
    --------------
     
    --------------
    CREATE TRIGGER `suppr`
    AFTER delete ON `test`
    FOR EACH ROW
    BEGIN
      call `trait` (old.date);
    END
    --------------
     
    --------------
    DROP TRIGGER IF EXISTS `modif`
    --------------
     
    --------------
    CREATE TRIGGER `modif`
    AFTER update ON `test`
    FOR EACH ROW
    BEGIN
      call `trait` (old.date);
    END
    --------------
     
    --------------
    select * from test
    --------------
     
    --------------
    select * from grouper
    --------------
     
    --------------
    insert into test (`date`, `kms`) values
      ('2015-12-01', 200), ('2015-11-01', 150), ('2015-11-17', 300), ('2015-10-13', 75), ('2015-10-23', 125), ('2015-12-25', 50)
    --------------
     
    --------------
    select * from test
    --------------
     
    +----+------------+-----+
    | id | date       | kms |
    +----+------------+-----+
    |  1 | 2015-12-01 | 200 |
    |  2 | 2015-11-01 | 150 |
    |  3 | 2015-11-17 | 300 |
    |  4 | 2015-10-13 |  75 |
    |  5 | 2015-10-23 | 125 |
    |  6 | 2015-12-25 |  50 |
    +----+------------+-----+
    --------------
    select * from grouper
    --------------
     
    +------+------+-----+
    | an   | mois | kms |
    +------+------+-----+
    | 2015 |   10 | 200 |
    | 2015 |   11 | 450 |
    | 2015 |   12 | 250 |
    +------+------+-----+
    --------------
    delete from test where date = '2015-11-01'
    --------------
     
    --------------
    select * from test
    --------------
     
    +----+------------+-----+
    | id | date       | kms |
    +----+------------+-----+
    |  1 | 2015-12-01 | 200 |
    |  3 | 2015-11-17 | 300 |
    |  4 | 2015-10-13 |  75 |
    |  5 | 2015-10-23 | 125 |
    |  6 | 2015-12-25 |  50 |
    +----+------------+-----+
    --------------
    select * from grouper
    --------------
     
    +------+------+-----+
    | an   | mois | kms |
    +------+------+-----+
    | 2015 |   10 | 200 |
    | 2015 |   11 | 300 |
    | 2015 |   12 | 250 |
    +------+------+-----+
    --------------
    update test set kms = 25 where date = '2015-10-13'
    --------------
     
    --------------
    select * from test
    --------------
     
    +----+------------+-----+
    | id | date       | kms |
    +----+------------+-----+
    |  1 | 2015-12-01 | 200 |
    |  3 | 2015-11-17 | 300 |
    |  4 | 2015-10-13 |  25 |
    |  5 | 2015-10-23 | 125 |
    |  6 | 2015-12-25 |  50 |
    +----+------------+-----+
    --------------
    select * from grouper
    --------------
     
    +------+------+-----+
    | an   | mois | kms |
    +------+------+-----+
    | 2015 |   10 | 150 |
    | 2015 |   11 | 300 |
    | 2015 |   12 | 250 |
    +------+------+-----+
    --------------
    COMMIT
    --------------
     
    --------------
    SET AUTOCOMMIT = 1
    --------------
     
     
    Appuyez sur une touche pour continuer...
    Je crois que tu vas avoir mal au pouce car tu vas devoir me mettre des '+1' sur tous mes messages !

    @+

  9. #9
    Membre éclairé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juin 2014
    Messages
    744
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Juin 2014
    Messages : 744
    Par défaut
    Bon merci.
    Ca fonctionne.
    Je pense avoir globalement compris, je vais l'adapter à "mon projet".

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    SET AUTOCOMMIT = 0;
    START TRANSACTION;
     
    COMMIT;
    SET AUTOCOMMIT = 1;
    Je n'ai pas compris à quoi sert cela.

    Je donne par petits bouts à me mesure que je comprends comment fonctionnent les outils que je manipulent.

    Pour les pouces, je les mets avec l'index.

    Merci je vais passer la semaine prochaine à utiliser ce que tu m'as fourni et dont je te remercie.

  10. #10
    Membre prolifique Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 868
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 868
    Par défaut
    Salut 69pierre.

    Désolé pour cette réponse tardive, mais j'ai encore eu quelques problèmes avec mon ordinateur.

    Citation Envoyé par 69pierre
    Je n'ai pas compris à quoi sert cela.
    En MySql, ce sont des déclaratives pour se mettre en mode "transaction".
    Ainsi dans le script, je peux valider "commit" ou rejeter "rollback" des insertions.
    Par défaut, je suis en mode "transaction" mais sans pouvoir rejeter. Autrement dit, tout est validée.

    A ton niveau, cela ne sert à rien.

    Citation Envoyé par 69pierre
    Pour les pouces, je les mets avec l'index.
    Merci !

    @+

  11. #11
    Membre éclairé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juin 2014
    Messages
    744
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Juin 2014
    Messages : 744
    Par défaut
    Bonjour.
    Je pense avoir compris comment faire, y'a plus qu'à...
    Je verrai bien les soucis rencontrés.

    Je me pose un problème de conception.

    Dans mon projet, je saisie des données tous les ans.

    Dans les faits, je modifie essentiellement les données de l'année en cours et accessoirement celles de l'année précédente.

    Pour optimiser mes requêtes, quelle est la meilleure méthode pour que la (les) procédure(s) stockée(s) crée une table par année et que les triggers ne la sollicite que pour l'année en cours et la précédent.
    Trouver un moyen pour qu'une procédure stockée travaille sur toute la base uniquement à la demande de l'utilisateur.

  12. #12
    Membre prolifique Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 868
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 868
    Par défaut
    Salut 69pierre.

    Quel est l'intérêt de faire une table par année ? As-tu un problème de volumétrie et par conséquent un problème de performance ?
    Si c'est ce que tu veux faire, la solution est de créer des partitions !

    Que signifie concrètement pour toi, "à la demande de l'utilisateur" ?

    @+

  13. #13
    Membre éclairé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juin 2014
    Messages
    744
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Juin 2014
    Messages : 744
    Par défaut
    Bonjour Artemus24.
    la solution est de créer des partitions !
    Qu'est ce que c'est ?
    Que signifie concrètement pour toi, "à la demande de l'utilisateur" ?
    A travers son IHM.
    Dans mon exemple imaginons que l'utilisateur de l'application ait mis à jour l'année 2008, il souhaite que tout les calculs soient refaits, un bouton sur son IHM le lui permet.

  14. #14
    Membre prolifique Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 868
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 868
    Par défaut
    Salut 69pierre.

    Citation Envoyé par 69pierre
    Qu'est ce que c'est ?
    Une façon de découper ta table physique en plusieurs sous-table physique.
    Ceci permet de stocker dans une sous-table physique, par exemple, l'année 2015, une autre sous-table physique l'année 2016 ...
    Au niveau de la table logique, cela ne change rien.

    Citation Envoyé par 69pierre
    A travers son IHM.
    Par hasard, tu ne travaillerais pas à la poste ?
    Drôle d'habitude de s'exprimer avec des abréviations dont vous êtes les seules à en faire un usage démesuré.
    La désignation d'aujourd'hui est simplement parler de l'utilisateur.

    Citation Envoyé par 69pierre
    Dans mon exemple imaginons que l'utilisateur de l'application ait mis à jour l'année 2008, il souhaite que tout les calculs soient refaits, un bouton sur son IHM le lui permet.
    Sinon, vu tes questions, je ne comprends pas bien ton problème.
    Est-ce un problème de faisabilité ou est-ce un problème de performance ?

    Une requête sera toujours plus lente si elle traite des millions de lignes, vis-à-vis de la même requête si elle traite quelques dizaines de lignes.
    Maintenant, il faut rester dans le domaine de l'acceptable. D'où l'importance de la performance !

    La conception de la base de données ne se fait pas essentiellement sur le dessin des relations entre ses différentes propriétés de ta base.
    En général, le MCD (modèle conceptuel des données) est la première étape pour concevoir ta base de données.

    La seconde étape, qui est très souvent délaissée est le MCT (modèle conceptuel des traitements).
    Il ne s'agit pas de trouve une solution au niveau des traitements à partir du MCD d'origine, sans changer celui-ci.
    Mais de trouver un compromis afin de rendre les traitements les plus performants.

    Cela consiste à revoir toutes la conception de ta base de données, en tenant compte cette fois-ci de l'aspect traitement.
    Le but est en effet de gagner du temps.

    La dégradation de ta base de données, vis-à-vis du MCD d'origine, passe par l'adjonction de procédure stockée, de trigger, de view qui permettent de faire croire que tu es encore dans le même modèle.
    Et je ne parle même pas de la facilité pour maintenir cette base en état de fonctionnement.

    Le cycle de vie d'une base de données passe par différentes étapes (ou version, voire aussi release), où chaque étape à sa raison d'être.
    Le MCD est l'aspect logique de ta base. Il y a ensuite l'aspect physique par la création des tables.
    Et je n'ai pas bien compris pourquoi on s'arrête là !

    Et quand viennent les traitement (les requêtes), on se rend compte d'un problème de performance à cause d'une mauvaise conception physique de la base.
    L'exemple qui me fait hérisser les cheveux sur la tête, c'est la jointure sur une quinzaine de tables ???
    Mais pourquoi mettre autant de table en relation en une seule fois ???

    Est-ce que le programmeur veut tout faire en une seule fois (très mauvaise idée) ?
    Est-ce un problème fonctionnelle qui impose des contrainte qui n'ont pas lieu d'être ?

    Mais quand tu voies ça, il y a un ratage quelque part !
    En ce point de la constatation, je ne sais pas dire si le problème vient du MCD ou du MCT ou de l'incompétence du développeur.

    Je pense souvent que l'on mélange le coté fonctionnelle qui est la finalité du traitement avec la façon de l'obtenir.
    Autrement dit, on s'intéresse qu'au résultat final mais pas dans la façon de l'obtenir, surtout sur des questions de performances de temps et de volumétrie.
    Alors que les contraintes les plus importantes sont informatiques et non fonctionnelles.

    @+

  15. #15
    Membre éclairé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juin 2014
    Messages
    744
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Juin 2014
    Messages : 744
    Par défaut
    Merci.
    Je vais digérer tout ce que tu m'as dit.
    Je reviendrais sur ce fil plus tard.
    Est-ce un problème de faisabilité ou est-ce un problème de performance ?
    Le pb de faisabilité est lié à mon incompétence "technique".
    Ce que je veux c'est optimiser la performance, prendre à travers mon exemple les bonnes habitudes.

  16. #16
    Membre Expert
    Homme Profil pro
    tripatouilleur de code pour améliorer mon quotidien boulistique
    Inscrit en
    Février 2008
    Messages
    946
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : tripatouilleur de code pour améliorer mon quotidien boulistique
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2008
    Messages : 946
    Par défaut
    Bonjour

    Artemus, IHM = Interface Homme Machine, terme que je n'ai vu employé que dans le domaine de l'informatique, en particulier sur Developpez.

    Pierre

  17. #17
    Membre prolifique Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 868
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 868
    Par défaut
    Salut pier.antoine.

    Le terme 'IHM' m'a surpris car c'est une façon vieillotte de s'exprimer qui date des années 60 ou 70.
    Cela fait des années que je n'ai plus vu cette expression.

    @+

  18. #18
    Membre éclairé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juin 2014
    Messages
    744
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Juin 2014
    Messages : 744
    Par défaut
    Il date des années 60-70 comme moi!

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

Discussions similaires

  1. [Oracle] PHP ne retourne que la dernière ligne d'un resultat d'une procedure stockée ORACLE
    Par tytous dans le forum PHP & Base de données
    Réponses: 0
    Dernier message: 08/06/2010, 07h57
  2. Appel procedure stockée oracle avec php
    Par CYCLOPE91440 dans le forum Oracle
    Réponses: 17
    Dernier message: 09/02/2007, 10h08
  3. [SQL-Server] Execution d'une procedure stockée SQL Serveur depuis PHP.
    Par gregb34 dans le forum PHP & Base de données
    Réponses: 5
    Dernier message: 04/05/2006, 01h06
  4. Appel a une procedure stockée en vba
    Par The_Nail dans le forum VBA Access
    Réponses: 36
    Dernier message: 01/04/2003, 16h44
  5. procedure stockée dans un dbbatch
    Par pram dans le forum XMLRAD
    Réponses: 4
    Dernier message: 07/02/2003, 16h35

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