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 :

UPDATE une table passée en paramètre


Sujet :

SQL Procédural MySQL

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Etudiant en alternance Licence dev Web/mobile
    Inscrit en
    Mars 2015
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Etudiant en alternance Licence dev Web/mobile

    Informations forums :
    Inscription : Mars 2015
    Messages : 26
    Points : 29
    Points
    29
    Par défaut UPDATE une table passée en paramètre
    Bonjour le forum, et merci d'avance à mes lecteurs,

    Alors voilà, je ne vous cache pas que je n'ai pas une énorme expérience en procédures stockées.
    Maiiiis je pensais tout de même savoir m'en servir pour en avoir fais quelques unes !

    Mieux qu'un long discours, voici une version simplifiée de ce que j'essai de faire:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    CREATE DEFINER=`root`@`localhost` PROCEDURE `updateTable`(input_table_name varchar(30), input_col_name varchar(30), input_id int, input_string_value varchar(30))
    BEGIN
    	UPDATE input_table_name
    	SET input_col_name = input_string_value
    	WHERE id = input_id;
    END
    Bon la comme ça c'est un peu inutile, mais l'idée est là.
    J'ai torturé google pour essayer de trouver des réponses mais sans trop de succès pour l'instant.
    Est-il donc possible d'utiliser les paramètres d'une procédure stockée de cette façon ?
    Je suis sur un projet en VBA, dans l'idée j'affiche le contenu de ma base sur une feuille excel.
    Quand je modifie une cellule je récupère le nom de la table, de la colonne, et l'ID, et j'appelle la procédure avec ces infos en paramètre pour réinjecter les modifications dans la BDD.

    Pour info, je récupère une erreur du type:
    La table test.input_table_name n'existe pas (ma DB s'appelle test).

    Je n'ai pas d'erreur en VBA, l'appel de la procédure se passe bien, et l'erreur intervient même si je passe les paramètres en dur dans les paramètres à l'appel.

    Voilà, si vous avez d'autres questions, n'hésitez pas, merci

  2. #2
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2014
    Messages
    352
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2014
    Messages : 352
    Points : 349
    Points
    349
    Par défaut
    Salut,
    D'abord ta procédure met à jour une seule colonne (input_col_name) là où id = input_id donc du coup je déduis que ta procédure n'a besoin que de 2 paramètres.

    Normalement ton script doit ressembler à ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    CREATE DEFINER=`root`@`localhost` PROCEDURE `updateTable`(input_string_value varchar(30), input_id int)
    BEGIN
    	UPDATE input_table_name SET input_col_name = input_string_value WHERE id = input_id;
    END
    Et comme indique le message "La table test.input_table_name n'existe pas" tu n'as pas une table nommée "input_table_name" dans la base "test".

  3. #3
    Membre averti Avatar de danyboy85
    Homme Profil pro
    Développeur Java
    Inscrit en
    Décembre 2005
    Messages
    548
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Décembre 2005
    Messages : 548
    Points : 312
    Points
    312
    Par défaut
    @Kasko Je pense que tu n'as pas bien compris son code : il tente de "variabiliser" les noms de tables et colonnes
    "Wash me away Clean your body of me Erase all the memories They'll only bring us pain And I've seen All i'll ever need"

  4. #4
    Membre averti Avatar de danyboy85
    Homme Profil pro
    Développeur Java
    Inscrit en
    Décembre 2005
    Messages
    548
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Décembre 2005
    Messages : 548
    Points : 312
    Points
    312
    Par défaut
    @Kasko Je pense que tu n'as pas bien compris son code : il tente de "variabiliser" les noms de tables et colonnes

    Edit : du coup je pense qu'il te manque un @ devant les noms de tables et champs :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    CREATE DEFINER=`root`@`localhost` PROCEDURE `updateTable`(input_table_name varchar(30), input_col_name varchar(30), input_id int, input_string_value varchar(30))
    BEGIN
    	UPDATE @input_table_name
    	SET @input_col_name = @input_string_value
    	WHERE id = @input_id;
    END
    "Wash me away Clean your body of me Erase all the memories They'll only bring us pain And I've seen All i'll ever need"

  5. #5
    Nouveau membre du Club
    Homme Profil pro
    Etudiant en alternance Licence dev Web/mobile
    Inscrit en
    Mars 2015
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Etudiant en alternance Licence dev Web/mobile

    Informations forums :
    Inscription : Mars 2015
    Messages : 26
    Points : 29
    Points
    29
    Par défaut
    Bonjour, et merci pour votre aide !

    @Kasko: J'ai bien besoin de mes 3 paramètres ! J'appel ma procédure stockée en lui passant, le nom de la table ou écrire, le nom de la colonne à l'intérieur de cette table, et l'id pour la ligne.
    Sans le nom de table ma fonction ne sait pas ou écrire !
    Et le code que tu me propose arrive au même point que moi, même en omettant mon paramètre input_table_name, c'est le nom de colonne input_col_name qui génère l'erreur:
    la colonne input_col_name n'existe pas.
    mySQL prend le nom du paramètre au lieu de son contenu dans la requête.. (je crois?)

    @danyboy85: Variabiliser le nom de mes tables/colonnes, c'est bien résumé oui
    Cependant la syntaxe que tu propose n'est pas reconnue (j'utilise mySQL workbench si ça importe)
    J'ai vu des syntaxes avec des @, mais il s'agissait de requêtes pour SQL Server, cependant je suis sur une base locale en mySQL..

    J'ai trouvé cette solution, qui semble fonctionner, mais que je ne trouve pas très propre (peut être que je me trompe?)
    L'issue final devra traiter une requête plus complexe sur une base avec des milliers d'entrées, j'aimerai opter pour la meilleure syntaxe en terme de performance.

    La solution bricolée:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    CREATE PROCEDURE `updateTable`(input_table_name varchar(30), input_col_name varchar(30), input_id int, input_string_value varchar(30))
    BEGIN
      SET @q = CONCAT('UPDATE ',input_table_name,' SET ', input_col_name, ' = "', input_string_value,'" WHERE id=',input_id);
      PREPARE stmt FROM @q;
      EXECUTE stmt;
    END |

    Je reste à l'écoute, merci d'avance

  6. #6
    Membre averti Avatar de danyboy85
    Homme Profil pro
    Développeur Java
    Inscrit en
    Décembre 2005
    Messages
    548
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Décembre 2005
    Messages : 548
    Points : 312
    Points
    312
    Par défaut
    Ça me parait pas mal, mais je me range à l’avis d'experts Mysql, qui sauront mieux que moi donner un avis sur la performance du code.
    "Wash me away Clean your body of me Erase all the memories They'll only bring us pain And I've seen All i'll ever need"

  7. #7
    Expert éminent sénior Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 381
    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 381
    Points : 19 065
    Points
    19 065
    Par défaut
    Salut à tous.

    @ Zywoon : je te propose une ébauche de ta procédure stockée.
    Il y a quatre tests à faire :
    1) table inconnue --> message d'erreur : 7001.
    2) colonne inconnue --> messafe d'erreur : 7002.
    3) tester la valeur du 'id'. Si elle n'existe pas, l'insérer dans la table.
    4) faire la mise à jour de la table, pour la colonne donnée.

    Comme tu va faire cela en masse, il te faut aussi un fichier mouchard, afin de garder la trace de ce que tu as fait.

    Il manque aussi dans le fichier mouchard, les références entre autre du nom de ta base access, ainsi que de la position dans ta table access.

    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
    --------------
    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,
      `texte`   VARCHAR(255)     NULL DEFAULT NULL
    ) ENGINE=InnoDB
      DEFAULT CHARSET=`latin1` COLLATE=`latin1_general_ci`
      ROW_FORMAT=COMPRESSED
    --------------
     
    --------------
    insert into `test` (`id`,`texte`) values (1, 'un'), (2, 'deux')
    --------------
     
    --------------
    select * from test
    --------------
     
    +----+-------+
    | id | texte |
    +----+-------+
    |  1 | un    |
    |  2 | deux  |
    +----+-------+
    --------------
    DROP TABLE IF EXISTS `mouchard`
    --------------
     
    --------------
    CREATE TABLE `mouchard` (
      `id`      INT          NOT NULL AUTO_INCREMENT PRIMARY KEY,
      `heure`   DATETIME     DEFAULT current_timestamp,
      `libelle` VARCHAR(255)     NULL DEFAULT NULL
    ) ENGINE=InnoDB
      DEFAULT CHARSET=`latin1` COLLATE=`latin1_general_ci`
      ROW_FORMAT=COMPRESSED
    --------------
     
    --------------
    DROP PROCEDURE IF EXISTS `updateTable`
    --------------
     
    --------------
    CREATE PROCEDURE `updateTable`
    (
      in input_table_name   varchar(30),
      in input_id           int,
      in input_col_name     varchar(30),
      in input_string_value varchar(30)
    )
    DETERMINISTIC
    NO SQL
    BEGIN
      DECLARE msg VARCHAR(255);
     
      DECLARE EXIT HANDLER FOR SQLSTATE '42S02'
      BEGIN
        SET msg = concat("Table inconnue \'", input_table_name, "\'");
            INSERT INTO mouchard (libelle) VALUES (msg);
        SIGNAL SQLSTATE VALUE '07001' SET MESSAGE_TEXT = msg, MYSQL_ERRNO = 7001;
      end;
     
      DECLARE EXIT HANDLER FOR SQLSTATE '42S22'
      BEGIN
        SET msg = concat("Colonne inconnue \'", input_col_name, "\' dans la table \'", input_table_name, "\'");
            INSERT INTO mouchard (libelle) VALUES (msg);
        SIGNAL SQLSTATE VALUE '07002' SET MESSAGE_TEXT = msg, MYSQL_ERRNO = 7002;
      end;
     
      SET @val=NULL;
     
      SET @req1 = concat("select id into @val from ", input_table_name, " where id = ", input_id);
     
      PREPARE            stmt1 FROM @req1;
      EXECUTE            stmt1;
      DEALLOCATE PREPARE stmt1;
     
      if (input_id = @val) then
        set @req2 = concat("update ", input_table_name, " set ", input_col_name, " = \'", input_string_value, "\' where id = ", input_id);
     
        PREPARE            stmt2 FROM @req2;
        EXECUTE            stmt2;
        DEALLOCATE PREPARE stmt2;
     
            INSERT INTO mouchard (libelle) VALUES (@req2);
      ELSE
        set @req3 = concat("insert into ", input_table_name, " (id, ", input_col_name, ") values (", input_id, ", \'", input_string_value, "\')");
     
        PREPARE            stmt3 FROM @req3;
        EXECUTE            stmt3;
        DEALLOCATE PREPARE stmt3;
            INSERT INTO mouchard (libelle) VALUES (@req3);
      END IF;
    END
    --------------
     
    --------------
    call `updateTable` ('test',  1, 'texte', 'ca marche')
    --------------
     
    --------------
    call `updateTable` ('test',  3, 'texte', 'bla bla bla')
    --------------
     
    --------------
    call `updateTable` ('test',  1, 'col',   'colonne')
    --------------
     
    ERROR 7002 (07002) at line 121: Colonne inconnue 'col' dans la table 'test'
    --------------
    call `updateTable` ('essai', 1, 'col',   'colonne')
    --------------
     
    ERROR 7001 (07001) at line 122: Table inconnue 'essai'
    --------------
    select * from test
    --------------
     
    +----+-------------+
    | id | texte       |
    +----+-------------+
    |  1 | ca marche   |
    |  2 | deux        |
    |  3 | bla bla bla |
    +----+-------------+
    --------------
    select * from mouchard
    --------------
     
    +----+---------------------+--------------------------------------------------------+
    | id | heure               | libelle                                                |
    +----+---------------------+--------------------------------------------------------+
    |  1 | 2015-12-03 17:27:24 | update test set texte = 'ca marche' where id = 1       |
    |  2 | 2015-12-03 17:27:24 | insert into test (id, texte) values (3, 'bla bla bla') |
    |  3 | 2015-12-03 17:27:24 | Colonne inconnue 'col' dans la table 'test'            |
    |  4 | 2015-12-03 17:27:24 | Table inconnue 'essai'                                 |
    +----+---------------------+--------------------------------------------------------+
    --------------
    COMMIT
    --------------
     
    --------------
    SET AUTOCOMMIT = 1
    --------------
     
     
    Appuyez sur une touche pour continuer...
    Comme j'ai travaillé pour toi, tu me mets plein de '+1' partout sur mes messages.


    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

  8. #8
    Nouveau membre du Club
    Homme Profil pro
    Etudiant en alternance Licence dev Web/mobile
    Inscrit en
    Mars 2015
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Etudiant en alternance Licence dev Web/mobile

    Informations forums :
    Inscription : Mars 2015
    Messages : 26
    Points : 29
    Points
    29
    Par défaut
    Bonjour Artemus24 !
    Et.. Wow
    Tu ne fais pas les choses à moitié..

    Merci beaucoup ! Je travaille encore sur le squelette du projet, mais ton code va m'être très utile.
    Je l'utiliserai et implémenterai tes ajouts petit à petit quand la base du projet sera fixée

    Je passe en résolu, merci à tous

  9. #9
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 136
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 136
    Points : 38 909
    Points
    38 909
    Billets dans le blog
    9
    Par défaut
    Désolé de jouer les rabat-joie mais je ne vois que des inconvénients à ce type de proc :
    - quand le format de la colonne ident de la table cible n'est pas compatible, votre requête ne fonctionnera pas
    - quand le format de la colonne ident de la table cible est autre chose que varchar(30), votre requete n'est pas sargable, d'où temps de réponse catastrophiques !
    - votre requête est de type SQL dynamique, c'est souvent interdit par la production, car aucune étude d'impact ne permet de les détecter, et les temps de réponse sont souvent rédhibitoires
    - si vous appelez votre proc pour une table dont la clef unique est multi-colonne, vous mettez à jour plusieurs lignes, sinon une seule, on ne maitrise donc pas le périmètre de l'update
    - si vous devez modifier plusieurs colonnes, voire toutes, il faut appeler autant de fois la proc, bonjour les temps de réponse, surtout compte tenu de ce que j'ai indiqué plus haut !

    Edit : et, j'avais oublié
    - la proc n'est pas utilisable pour mettre à null une colonne nullable

    Donc à part si votre proc a un but uniquement didactique, A FUIR ABSOLUMENT...

  10. #10
    Expert éminent sénior Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 381
    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 381
    Points : 19 065
    Points
    19 065
    Par défaut
    Salut Escartefigue.

    Citation Envoyé par Escartefigue
    Désolé de jouer les rabat-joie mais je ne vois que des inconvénients à ce type de proc
    Tant que la critique est constructive, elle est toujours la bienvenue. Mais maintenant, il faut proposer une solution au problème de Zywoon.

    Si tu savais les aberrations que l'on voie parfois en production, tu t'arracherais les cheveux !

    Je suis d'accord sur le "sql dynamique", surtout quand on a une grosse volumétrie.
    On utilise de préférence un 'LOAD DATA LOCAL INFILE' qui est mieux adapté au chargement des tables depuis un fichier.

    Zywoon nous demande de l'aide pour un besoin spécifique, mais il n'a pas expliqué la nature de son problème. Tout ce que j'ai fait, c'est répondre à son attente.

    Citation Envoyé par Zywoon
    Quand je modifie une cellule je récupère le nom de la table, de la colonne, et l'ID, et j'appelle la procédure avec ces infos en paramètre pour réinjecter les modifications dans la BDD.
    Ça, c'est son besoin ! Pourquoi ne pas attendre d'avoir fini la modification de sa feuille excel, pour la transférer dans la table mysql, par un 'load data local infile' ?

    Bon, maintenant a-t-il soumis cette solution à son chef de projet et qu'est-ce qu'il en pense ?
    A moins que cela ne soit pas dans le cadre professionnel et qu'il peut se permettre de faire du gaspillage de temps.

    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

  11. #11
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 136
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 136
    Points : 38 909
    Points
    38 909
    Billets dans le blog
    9
    Par défaut
    Des aberrations en prod, j'en vois tous les jours, pas plus tard que ce matin, une table contenant une dizaine de dates et toutes déclarées en format CHAR

    Pour autant, je considère que c'est mon devoir d'alerter quand une solution envisagée n'est pas viable, car une fois en prod c'est souvent trop tard, et en tout cas tellement plus couteux à réparer !

    Ici on est sur une solution qui présente beaucoup d'inconvénients majeurs, et pour laquelle je ne vois aucun avantage (s'il y en a, j'aimerai bien les connaitre...)

    Dans le post initial, il n'est pas indiqué ce que l'on veut atteindre comme résultat, mais comment le demandeur a commencé à construire sa solution, ce n'est pas la même chose
    Dans ce cas, il est plus sage de reformuler ce que l'on veut obtenir fonctionnellement, pour envisager les différentes solutions avec leurs avantages et inconvénients, puis retenir la meilleure
    Sachant que le meilleur se décide en concertation avec les utilisateurs, et la production

    Après libre à chacun de faire comme bon lui semble, sous réserve que l'entreprise lui donne le feu vert

  12. #12
    Nouveau membre du Club
    Homme Profil pro
    Etudiant en alternance Licence dev Web/mobile
    Inscrit en
    Mars 2015
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Etudiant en alternance Licence dev Web/mobile

    Informations forums :
    Inscription : Mars 2015
    Messages : 26
    Points : 29
    Points
    29
    Par défaut
    Bonjour à tout les deux !

    C'est bien dans le cadre professionnel que j'oeuvre !
    Mais je suis plus ou moins libre de mes choix, je suis en phase de recherche et développement, je dois proposer une solution viable.
    Libre à moi d'utiliser telle ou telle syntaxe après.

    Je vais me rencarder sur le load data local infile !
    Je pensais que justement sur une feuille excel de 5.000 lignes, ce serait plus rapide d'insérer spécifiquement des modifs, avec une table adaptée et des updates
    plutôt que de recharger tout le fichier excel dans la base ... ?

    J'ai même pensé à adapter mes table par exemple, avec des coordonnées row/column..

    Si vous avez des conseils..
    Je détail un peu plus mon projet:
    J'ai un gros fichier excel à partir duquel je peux ouvrir divers tableaux de bords etc.
    J'aimerai ajouter un template, pour afficher le contenu d'une table, et pouvoir le modifier.
    Il faut donc que ce soit quelque chose de général, qui s'adapte selon l'endroit d'ou j'appel mon template, qui affichera tel ou tel table,
    et en mesure de mettre à jour la DB en cas de modif.

    PS: Merci pour votre aide

    EDIT: Il est aussi possible que je doive afficher le résultat d'une jointure de table, et dans ce cas j'ai du mal à voir comment réinjecter les modifs dans la DB..

  13. #13
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 136
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 136
    Points : 38 909
    Points
    38 909
    Billets dans le blog
    9
    Par défaut
    Si je comprends bien, vous avez la possibilité de charger le contenu de telle ou telle table dans votre excel, et selon la ou les colonne(s) de la table que vous modifiez, vous voulez répercuter le contenu excel dans la table.

    Techniquement, vous devrez donc construire une requête dynamique, qui tient compte du nom variable de la table et de la ou des colonnes
    Vous devez ne mettre à jour que les lignes souhaitées, il faut donc construire votre where non pas sur une seule colonne, mais dynamiquement aussi, en respectant le format pour que la syntaxe de la requête soit valide et indexable

    Problèmes :
    • il vous faut donc soit importer la description de chacune de vos tables dans votre excel, soit faire cette description manuellement et s'assurer en permanence que la description excel est à jour
    • il vous faut ensuite traduire le format de chaque colonne excel en format indexable pour la requete et compatible avec les différentes colonnes
    • quand vous voudrez faire votre mise à jour, excel n'a posé aucun verrou lors de la lecture, vous serez donc confrontés à des mises à jour concurrentes et des risques de dégradation des données quelqu'un ayant pu modifier des données après chargement dans excel
    • ce mode de fonctionnement est très dangereux si votre modèle de données ne gère pas les contraintes d'intégrité, vous allez potentiellement créer des orphelins (ex : lignes de commande sans commande)
    • comment allez vous gérer les commit et rollback depuis excel



    En résumé, je dirai que charger excel, soit via des liens ODBC pour se connecter sur la base, soit par chargement d'un fichier, pourquoi pas
    Mais faire des mises à jour, non

  14. #14
    Expert éminent sénior Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 381
    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 381
    Points : 19 065
    Points
    19 065
    Par défaut
    Salut à tous.

    Citation Envoyé par Escartefigue
    Pour autant, je considère que c'est mon devoir d'alerter quand une solution envisagée n'est pas viable, car une fois en prod c'est souvent trop tard, et en tout cas tellement plus coûteux à réparer !
    Je suis d'accord avec toi.

    Citation Envoyé par Escartefigue
    Ici on est sur une solution qui présente beaucoup d'inconvénients majeurs, et pour laquelle je ne vois aucun avantage (s'il y en a, j'aimerai bien les connaitre...)
    Le seul avantage est que je réponds à sa question. Dans la réalité d'un projet en production, je ne procéderai pas ainsi, ni toi d'ailleurs.

    Citation Envoyé par Escartefigue
    Dans ce cas, il est plus sage de reformuler ce que l'on veut obtenir fonctionnellement, pour envisager les différentes solutions avec leurs avantages et inconvénients, puis retenir la meilleure
    Ça, c'est la théorie. Le développeur est souvent à court de temps pour trouver une bonne solution.
    De plus, on lui impose des contraintes, non prévue au départ, juste pour satisfaire un utilisateur, ou la prod.
    Et au final, avec toute la bonne volonté dont tu disposes, tu te retrouves avec une solution dégradée, à l'identique de ce tableau de Picasso :



    où tout est de travers, et non conforme à ce que l'on voulait faire au départ.

    Citation Envoyé par Zywoon
    C'est bien dans le cadre professionnel que j'oeuvre !
    Aïe !

    Citation Envoyé par Zywoon
    J'aimerai ajouter un template, pour afficher le contenu d'une table, et pouvoir le modifier.
    Vous vous êtes trompé d'outil. Le mieux est d'utiliser ceci "connector/odbc" : https://dev.mysql.com/downloads/connector/odbc/

    Personnellement, quand j'ai besoin de faire un traitement un peu plus contraignant, avec des tas de calculs, je préfère le faire en 'C', en utilisant "connector/C" : https://dev.mysql.com/downloads/connector/c/
    Je me sens plus à l'aise qu'avec le php, que je considère bien adapté pour faire du web, mais pas pour faire des calculs.

    En fait, on s'écarte de la question de départ.

    Si tu as d'autres questions sur MySql, tu peux les poser, sinon, il faudra te rendre dans le forum consacré à Excel et à ODBC, pour avoir des réponses plus adapté à ta problématique.

    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

  15. #15
    Nouveau membre du Club
    Homme Profil pro
    Etudiant en alternance Licence dev Web/mobile
    Inscrit en
    Mars 2015
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Etudiant en alternance Licence dev Web/mobile

    Informations forums :
    Inscription : Mars 2015
    Messages : 26
    Points : 29
    Points
    29
    Par défaut
    Merci pour ces précisions ! Malheureusement ce n'est pas moi qui décide, et c'est bel et bien de la mise à jour que je dois réussir à faire,
    Je vais donc essayer de faire au mieux..

    Qu'en est-il selon vous de la solution de Artemus24 avec le "LOAD DATA INFILE" ?
    Est-ce une solution plus saine, et envisageable sur quelques milliers de lignes?

    EDIT: J'utilise effectivement ODBC qui me permet de me connecter à ma base.

  16. #16
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 136
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 136
    Points : 38 909
    Points
    38 909
    Billets dans le blog
    9
    Par défaut
    Le load data infile est un moyen technique de charger votre table DB2 depuis un fichier plat, mais comme c'est le contenu de votre excel qui permettrait de créer ce fichier qui ne peut pas être maitrisé, que vous passiez par un load ou un update via lien ODBC, c'est pareil

    De plus, entre le moment où vous avez chargé votre excel, et le moment où vous feriez l'export du fichier afin de faire le load, il a pu y avoir des modifs, ajouts et suppression dans la table cible.
    Du coup, si vous faites du load en mode replace, les modifs et ajouts des collègues sont perdues
    Si vous faites du load en mode ajout, seules vos lignes ajoutées dans excel (nouvelles valeurs d'index) seront prises en compte

    Non décidément, vous n'avez pas d'autre choix que de créer une application

  17. #17
    Expert éminent sénior Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 381
    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 381
    Points : 19 065
    Points
    19 065
    Par défaut
    Salut à tous.

    A la demande de Zywoon, voici un exemple de "load data local infile".

    Voici le fichier que je désire charger dans une table "MySql". C'est juste un test :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    "fr","dijon bourgogne","---","bo",500000,200,150,"10/12/2015 15:20",
    "fr","paris ile de france","---","il",2000000,100,50,"15/06/2015 07:15",
    "fr","nice paca","---","pa",100000,250,75,"25/07/2015 19:58",
    "fr","paca","---","pa",100000,250,75,"25/07/2015 19:58",
    Et voici le chargement de la table :
    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
    --------------
    SET AUTOCOMMIT = 0
    --------------
     
    --------------
    START TRANSACTION
    --------------
     
    --------------
    DROP DATABASE IF EXISTS `base`
    --------------
     
    --------------
    CREATE DATABASE IF NOT EXISTS `base`
            DEFAULT CHARACTER SET `latin1`
            DEFAULT COLLATE       `latin1_general_ci`
    --------------
     
    --------------
    DROP TABLE IF EXISTS Cities
    --------------
     
    --------------
    CREATE TABLE Cities (
        Country     CHAR(2),
        City        CHAR(22),
        AccentCity  CHAR(3),
        Region      CHAR(2),
        Population  INT UNSIGNED NULL DEFAULT NULL,
        Latitude    FLOAT,
        Longitude   FLOAT,
            Date        DATETIME
    ) ENGINE=InnoDB
      DEFAULT CHARSET=`latin1` COLLATE=`latin1_general_ci`
    --------------
     
    --------------
    TRUNCATE Cities
    --------------
     
    --------------
    set unique_checks      = 0
    --------------
     
    --------------
    set foreign_key_checks = 0
    --------------
     
    --------------
    set sql_log_bin        = 0
    --------------
     
    --------------
    alter table Cities DISABLE KEYS
    --------------
     
    --------------
    commit
    --------------
     
    --------------
    LOAD DATA LOCAL INFILE 'Fichier.txt'
            INTO TABLE `Cities`
        CHARACTER SET latin1
            FIELDS  TERMINATED BY ','
                            ENCLOSED   BY '"'
                            ESCAPED    BY '\\'
            LINES   TERMINATED BY '\n'
        IGNORE 0 LINES
        (@F1, @F2, @F3, @F4, Population, Latitude, Longitude, @F8)
            set Country    = trim(@F1),
                City       = trim(@F2),
                AccentCity = trim(@F3),
                Region     = trim(@F4),
                    Date       = outils.chgdate(@F8)
    --------------
     
    --------------
    commit
    --------------
     
    --------------
    alter table Cities ENABLE KEYS
    --------------
     
    --------------
    set unique_checks      = 1
    --------------
     
    --------------
    set foreign_key_checks = 1
    --------------
     
    --------------
    set sql_log_bin        = 1
    --------------
     
    --------------
    commit
    --------------
     
    --------------
    select  concat('>', Country,   '<') as 'Country',
                    concat('>', City,      '<') as 'City',
                    concat('>', AccentCity,'<') as 'AccentCity',
                    concat('>', Region,    '<') as 'Region',
                    concat('>', Population,'<') as 'Population',
                    concat('>', Latitude,  '<') as 'Latitude',
                    concat('>', Longitude, '<') as 'Longitude',
                    concat('>', date,      '<') as 'Date'
    from `Cities`
    --------------
     
    +---------+-----------------------+------------+--------+------------+----------+-----------+-----------------------+
    | Country | City                  | AccentCity | Region | Population | Latitude | Longitude | Date                  |
    +---------+-----------------------+------------+--------+------------+----------+-----------+-----------------------+
    | >fr<    | >dijon bourgogne<     | >---<      | >bo<   | >500000<   | >200<    | >150<     | >2015-12-10 15:20:00< |
    | >fr<    | >paris ile de france< | >---<      | >il<   | >2000000<  | >100<    | >50<      | >2015-06-15 07:15:00< |
    | >fr<    | >nice paca<           | >---<      | >pa<   | >100000<   | >250<    | >75<      | >2015-07-25 19:58:00< |
    | >fr<    | >paca<                | >---<      | >pa<   | >100000<   | >250<    | >75<      | >2015-07-25 19:58:00< |
    +---------+-----------------------+------------+--------+------------+----------+-----------+-----------------------+
    --------------
    COMMIT
    --------------
     
    --------------
    SET AUTOCOMMIT = 0
    --------------
     
     
    Appuyez sur une touche pour continuer...
    Un "load data local infile" sert à charger une table qui au préalable n'existe pas.
    Mais si vous désirez mettre à jour une table, à partir d'un fichier excel, le mieux, comme le dit Escartefigue, est de créer une application.
    Ni le "load data local infile", ni la procédure stockée sont destinés à faire le lien entre deux environnements différents, pour faire des mises à jour.

    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

  18. #18
    Nouveau membre du Club
    Homme Profil pro
    Etudiant en alternance Licence dev Web/mobile
    Inscrit en
    Mars 2015
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Etudiant en alternance Licence dev Web/mobile

    Informations forums :
    Inscription : Mars 2015
    Messages : 26
    Points : 29
    Points
    29
    Par défaut
    Très bien, merci beaucoup pour votre aide !
    Je vais faire le point sur tout ça, et voir ou je vais.

    Je passerai surement vous dire quelle solution j'ai utilisé d'ici quelques temps !

    Bonne continuation

Discussions similaires

  1. Parcourir table passée en paramètre d'une procédure
    Par Bonosvox dans le forum PL/SQL
    Réponses: 1
    Dernier message: 08/04/2013, 11h12
  2. Réponses: 14
    Dernier message: 29/07/2008, 12h33
  3. Réponses: 4
    Dernier message: 20/05/2006, 17h30
  4. Réponses: 2
    Dernier message: 21/04/2006, 12h09
  5. Réponses: 3
    Dernier message: 01/02/2006, 21h31

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