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

Requêtes MySQL Discussion :

Requête incluant une primary key


Sujet :

Requêtes MySQL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 414
    Par défaut Requête incluant une primary key
    Bonjour à tous,
    Ce matin je bute sur un problème que je n’ai jamais eu à résoudre auparavant.
    Je cherche à sélectionner une ou plusieurs colonnes avec une contrainte where sur l’index.
    Expliqué autrement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT *  from table WHERE (table.COLUMN_NAME Primary key) = 34
    Si qq peut m’indiquer une piste, je lui en saurais gré !!!
    D’avance merci

    PS : Je reprends une vieille base dont les primary key varient sur chaque table ??!!

  2. #2
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 633
    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 633
    Billets dans le blog
    10
    Par défaut
    Bonjour,

    Je ne vois pas où est la difficulté, ou alors je n'ai pas compris votre besoin

    Soit la table T1, dotée des colonnes Col1, Col2 et Col3

    Si la clef primaire est Col1, alors la requête est tout simplement
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    select Col1
         , Col2
         , Col3
    where Col1=34
    Vu que pour la PK, l'index est créé automatiquement, vous êtes certains d'avoir au moins un index satisfaisant le prédicat de filtrage, il n'est toutefois pas certain que ce soit l'index de la PK qui sera choisi par l'optimiseur. Mais ça n'a aucune importance, fonctionnellement, le résultat sera celui souhaité

  3. #3
    Membre chevronné Avatar de isabelle.letrong
    Femme Profil pro
    Conseil - Consultante en systèmes d'information
    Inscrit en
    Juillet 2010
    Messages
    109
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Conseil - Consultante en systèmes d'information
    Secteur : Conseil

    Informations forums :
    Inscription : Juillet 2010
    Messages : 109
    Par défaut
    Bonjour bronon,

    Citation Envoyé par bronon Voir le message
    Je reprends une vieille base dont les primary key varient sur chaque table ??!!
    je ne vois pas trop ce que vous voulez dire par 'les primary key varient sur chaque table'.
    Effectivement chaque table a sa propre clé primaire qui peut être un entier technique, ou encore l'union de colonnes 'porteuses de sens'. C'est une question de (bonne) conception du modèle...
    Pourriez-vous préciser votre difficulté ?

  4. #4
    Membre éclairé
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 414
    Par défaut
    Merci pour vos retours,
    Je précise mon problème comme vous le souhaitiez.
    Aujourd’hui je fais la requête suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT variable FROM table1 WHERE id = valeur
    Le seul problème que j’ai est que l’id est la clé primaire de la table mais que cette clé primaire change de nom souvent en fonction de la table, par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     table 1 clé primaire id
     table 2 clé primaire idClient
     table 3 clé primaire idSoc
     table 4 clé primaire email
    Etc.
    Ceci oblige à une lourde programmation puisqu’il faut indiquer en clair l’id de référence.
    Je voudrais dans la clause WHERE définir l’id par la clé primaire de la table en question
    J’ai retourné la question un peu dans tous les sens notamment en utilisant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    INFORMATION_SCHEMA.KEY_COLUMN_USAGE
    sans succès !
    Ma question est comment faire ?

    J’espère avoir été + clair
    D’avance merci

  5. #5
    Membre chevronné Avatar de isabelle.letrong
    Femme Profil pro
    Conseil - Consultante en systèmes d'information
    Inscrit en
    Juillet 2010
    Messages
    109
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Conseil - Consultante en systèmes d'information
    Secteur : Conseil

    Informations forums :
    Inscription : Juillet 2010
    Messages : 109
    Par défaut
    bronon,

    En s'appuyant sur le catalogue MySQL on peut tout faire, notamment allez chercher des noms de colonnes, de clés, puis construire des requêtes dynamiques mais, vraiment, je ne comprends pas le sens de ce que vous cherchez à faire.
    Par ailleurs, une clé primaire peut être composite et donc répartie sur plusieurs colonnes d'une table , ce qui implique dans ce cas que la restriction (clause WHERE) doit nommer plusieurs colonnes. Est-ce que tout ceci a bien du sens ?

    Peut-être une explication sur la finalité du développement en cours nous éclairerait.

  6. #6
    Membre éclairé
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 414
    Par défaut
    Je cherche simplement (!) à faire si C possible

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT variable FROM table1 WHERE clé primaire de la table1 = valeur

  7. #7
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 633
    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 633
    Billets dans le blog
    10
    Par défaut
    Comme indiqué par Isabelle, il est bien sur possible d'exploiter le catalogue pour connaitre le nom de la ou des colonnes PK de chacune des tables, mais pour autant, les colonnes de la clause select ne peuvent pas être les mêmes. Du coup l'intérêt semble plus que limité...
    Sans rentrer dans le langage SQL ni autre considération technique, quel est le besoin fonctionnel ?

  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 914
    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 914
    Par défaut
    Salut bronon.

    Pour répondre à votre problème, personne ne procède ainsi.

    Mais au préalable, vous devez connaitre votre dictionnaire des données.
    C'est-à-dire le nom de toutes les colonnes de toutes vos tables, sachant qui est clef primaire, qui est clef étrangère, et qui est informationnelle.

    Ensuite, si votre dictionnaire est bien conçu, un nom de colonne désignant un usage particulier, aura le même nom dans toute la base de données.
    J'ai pris l'habitude de nommer mes clefs primaire auto incrémenté par "id" pour identifiant, même si elle concerne des tables différentes.
    Quand je fais référence à ces clefs primaire, au travers des clefs étrangère, j'indique "clef" ou "id" suivi du nom de la table.
    Par exemple "clef_personnel" pour la clef étrangère qui va pointer sur la colonne "id" (donc la clef primaire) de la table "personnel".

    Si vous désirez fusionner vos deux requêtes, dans ce cas, vous devez la construire.
    Or je constate que c'est ce que vous faites déjà en php.

    Il y a un léger problème avec votre requête car elle ne traite que les cas où la clef primaire est constituée que d'une seule colonne.

    Citation Envoyé par Bronon
    Malheureusement cette BD a été conçu il y a au moins 15 ans
    Ce n'est pas une excuse.

    Citation Envoyé par Bronon
    et fil du temps chacun à apporter ses modifications, ses erreurs…
    Si vous considérez cela comme des erreurs, pourquoi ne pas les corriger par vous-même ?

    Citation Envoyé par isabelle.letrong
    Désolée, mais nous sommes au moins trois à ne pas comprendre pourquoi "j'ai besoin de ces requêtes".
    Cinq, après Sebwar, car je rentre aussi dans la danse.

    Escartefigue me reprendra, mais vous désirez utiliser le "meta language" de mysql pour faire du sql dynamique.

    Donc en partant de votre idée en en faisant cela en mysql :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT *  from table WHERE (table.COLUMN_NAME Primary key) = 34
    Pour construire votre requête, je propose une procédure stockée, que voici :
    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
    --------------
    SET AUTOCOMMIT = 0
    --------------
     
    --------------
    START TRANSACTION
    --------------
     
    --------------
    DROP PROCEDURE IF EXISTS `build`
    --------------
     
    --------------
    CREATE PROCEDURE `build`
    (
      in _base   varchar(255),
      in _table  varchar(255),
      in _col    varchar(255),
      in _where  varchar(255)
    )
    DETERMINISTIC
    NO SQL
    BEGIN
    DECLARE _fin INTEGER DEFAULT 1;
    DECLARE _z   varchar(255);
    DECLARE _tab CURSOR FOR SELECT  concat(' where (', group_concat(column_name order by ordinal_position separator ','),') = ')
                              from  information_schema.key_column_usage
                             where  table_schema    =  _base
                               and  table_name      =  _table
                               and  constraint_name = 'primary'
                          order by  table_schema, table_name;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET _fin = 0;
     
    OPEN  _tab;
    FETCH _tab INTO _z;
    CLOSE _tab;
     
    set @req = concat("select ",_col," from ",_base,'.',_table,_z,_where);
     
    select @req;
     
    PREPARE            stmt1 FROM @req;
    EXECUTE            stmt1;
    DEALLOCATE PREPARE stmt1;
     
    END
    --------------
     
    --------------
    call `build` ('base','test','*','3')
    --------------
     
    +----------------------------------------+
    | @req                                   |
    +----------------------------------------+
    | select * from base.test where (id) = 3 |
    +----------------------------------------+
    +----+-------+
    | id | val   |
    +----+-------+
    |  3 | trois |
    +----+-------+
    --------------
    COMMIT
    --------------
     
    --------------
    SET AUTOCOMMIT = 1
    --------------
     
    Appuyez sur une touche pour continuer...
    Je me suis amusé à créer cette procédure stockée pour vous montrer que l'on automatiser la construction d'une requête dynamique.

    @+

  9. #9
    Membre éclairé
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 414
    Par défaut
    Merci pour ta réponse que je dois regarder avec précision car je suis très peu familier avec cette manière de « scripter »

    Pour finaliser une partie de mon problème consistant à, pour l'update d'une colonne, récupérer le nom de la table ainsi que la primary key de la table :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    SELECT ic.TABLE_NAME AS nomTable, ic.COLUMN_NAME AS nomCol, icu.COLUMN_NAME AS ident FROM INFORMATION_SCHEMA.COLUMNS ic RIGHT JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE icu ON icu.CONSTRAINT_NAME = 'primary' AND icu.TABLE_NAME = ic.TABLE_NAME AND icu.table_schema = 'xxxxxxx' WHERE ic.COLUMN_NAME = 'yyyyyyy' AND ic.table_schema = '"$rubrique"'
    Ce qui a l'avantage de faire « le job » mais très lentement

    Maintenant j'aimerai inclure cette requête dans celle de l'update pour n'avoir qu'une requête au total mais là je pense que j'approche la mission impossible !

  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 914
    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 914
    Par défaut
    Salut Salut bronon.

    Comme je l'ai dit précédemment, vous devez construire votre requête.
    Quand vous récupérez vos noms de colonnes, ce sont des chaînes de caractères et non des colonnes de tables.
    C'est ce que je fais dans le curseur de la procédure stockée.
    Je récupère toutes les colonnes faisant partie de la clef primaire.
    La plupart du temps, cela va se résumer à une colonne.
    Mais si vous en avez deux ou plus, la clause where va s'écrire ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    where (col1,col2,col3) = (4, 12, 8);
    C'est la raison des parenthèses autour de la colonne "id" dans mon exemple.

    Et pour mettre en forme ce genre de traitement, rien de tel qu'une procédure stockée.

    @+

Discussions similaires

  1. [AC-2010] Ajouter une primary Key à une requête union
    Par gegematic dans le forum Requêtes et SQL.
    Réponses: 2
    Dernier message: 27/02/2014, 16h58
  2. auto-incrémentation sur une primary key avec sql server
    Par pops4 dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 24/05/2007, 14h24
  3. [MySQL] Réinitialiser une 'Primary Key'
    Par thannane dans le forum PHP & Base de données
    Réponses: 5
    Dernier message: 07/02/2007, 23h04
  4. INDEX utilisé par une Primary Key
    Par Wurlitzer dans le forum Oracle
    Réponses: 2
    Dernier message: 29/06/2006, 11h42
  5. [TYPE DE CHAMPS] Quel type pour une primary key ?
    Par guy2004 dans le forum SQL Procédural
    Réponses: 4
    Dernier message: 25/03/2006, 12h23

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