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 :

Gérer une clé unique année/numéro


Sujet :

Requêtes MySQL

  1. #1
    Membre à l'essai
    Inscrit en
    Décembre 2006
    Messages
    18
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 18
    Points : 13
    Points
    13
    Par défaut Gérer une clé unique année/numéro
    Bonsoir,

    Je travaille sur une application PHP/MySQL qui doit gérer une entité "dossier", identifiée par un entier (en AUTO_INCREMENT), et par une chaîne du type [année]-[numéro], pour l'utilisateur final. C'est sur cet "identifiant secondaire" que je coince...

    L'année est celle de la création du dossier ; le numéro doit être unique pour l'année concernée seulement (donc remis à zéro chaque année).

    Lors d'un INSERT, récupérer l'année en cours n'est pas une difficulté. Je pense créer l'identifiant secondaire par l'intermédiaire d'un trigger (before insert) qui concatènerait les deux éléments (il me semble que c'est possible sur MySQL 5).
    Mais gérer le compteur pour l'obtention du numéro d'ordre me pose problème...
    Devrais-je utiliser une table séparée, mise à jour à chaque INSERT ? Mais comment gérer la remise à zéro de façon fiable ?

    Auriez vous une idée sur la question ?

    Merci par avance pour votre aide,

    Cordialement,

  2. #2
    Rédacteur/Modérateur

    Avatar de Antoun
    Homme Profil pro
    Architecte décisionnel
    Inscrit en
    Octobre 2006
    Messages
    6 281
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Architecte décisionnel
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2006
    Messages : 6 281
    Points : 11 737
    Points
    11 737
    Par défaut
    Devrais-je utiliser une table séparée, mise à jour à chaque INSERT ? Mais comment gérer la remise à zéro de façon fiable ?
    Non, il te suffit d'une requête pour rechercher le + gros numéro de l'année :

    new.numero = COALESCE(
    (SELECT MAX(numero)
    FROM ta_table
    WHERE annee = new.annee
    ) + 1,
    0 ) ;
    Antoun
    Expert Essbase, BO, SQL

    La bible d'Essbase, 2ème édition

  3. #3
    Membre à l'essai
    Inscrit en
    Décembre 2006
    Messages
    18
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 18
    Points : 13
    Points
    13
    Par défaut
    Merci pour cette réponse rapide (et plus que pertinente )

    Si je résume (pour moi-même), il me faut une table du type :

    dossier
    --------
    id
    annee-numero
    numero
    annee
    ...

    A chaque INSERT, COALESCE(...) me renvoie le plus grand numéro de l'année en cours (+1), ce qui me donne "numero" et "annee-numero" (après concaténation).

    Pas besoin de trigger, alors ?

    Petit pinaillage, à quoi sert le 0 dans :

    new.numero = COALESCE(
    (SELECT MAX(numero)
    FROM ta_table
    WHERE annee = new.annee
    ) + 1,
    0 ) ;

  4. #4
    Membre expert
    Avatar de Alexandre T
    Homme Profil pro
    Chef de projets AMO
    Inscrit en
    Mai 2002
    Messages
    1 213
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Chef de projets AMO
    Secteur : Transports

    Informations forums :
    Inscription : Mai 2002
    Messages : 1 213
    Points : 3 001
    Points
    3 001
    Par défaut
    Citation Envoyé par LeWaké
    Si je résume (pour moi-même), il me faut une table du type :

    dossier
    --------
    id
    annee-numero
    numero
    annee
    ...
    Non, une table comme ceci est suffisante. Evitez la redondance d'informations :

    dossier
    --------
    id
    numero
    annee
    ...
    Par contre, vous pouvez utiliser une vue pour vos sélections :
    v_dossier
    ---------
    id
    numero-annee

    Cette vue sera automatiquement mise à jour par le moteur et vous évitera toute erreur / oubli lors du développement de l'application.
    Alexandre Tranchant
    Chef de projet AMO pour le Cerema.
    Retrouvez mes articles sur PHP et Symfony

  5. #5
    Membre à l'essai
    Inscrit en
    Décembre 2006
    Messages
    18
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 18
    Points : 13
    Points
    13
    Par défaut
    Merci !

  6. #6
    Rédacteur/Modérateur

    Avatar de Antoun
    Homme Profil pro
    Architecte décisionnel
    Inscrit en
    Octobre 2006
    Messages
    6 281
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Architecte décisionnel
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2006
    Messages : 6 281
    Points : 11 737
    Points
    11 737
    Par défaut
    Quant au COALESCE(..., 0), il permet de numéroter à 0 le premier dossier de l'année (pour lequel le SELECT MAX()... renvoie un NULL).
    Antoun
    Expert Essbase, BO, SQL

    La bible d'Essbase, 2ème édition

  7. #7
    Membre à l'essai
    Inscrit en
    Décembre 2006
    Messages
    18
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 18
    Points : 13
    Points
    13
    Par défaut
    Compris : dans mon cas ça sera plutôt 1...
    Merci Antoun !

  8. #8
    Membre à l'essai
    Inscrit en
    Décembre 2006
    Messages
    18
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 18
    Points : 13
    Points
    13
    Par défaut
    Arf, désolé, je galère encore, ma requête* ne passe pas parce que ma sous-requête fait appel à la même table que le INSERT...
    Quelle stratégie devrais-je adopter dans ce cas ?


    *
    INSERT INTO dossier
    (idDossier, numero, heure_creation, jour_creation, mois_creation, annee_creation)
    VALUES
    (null, COALESCE((SELECT MAX(numero) FROM dossier WHERE annee_creation = '2006') + 1, 1 ), '23:25:9', '30', '12', '2006');

  9. #9
    Rédacteur/Modérateur

    Avatar de Antoun
    Homme Profil pro
    Architecte décisionnel
    Inscrit en
    Octobre 2006
    Messages
    6 281
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Architecte décisionnel
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2006
    Messages : 6 281
    Points : 11 737
    Points
    11 737
    Par défaut
    ce gag-là se contourne en utilisant une sous-sous-requête dans le FROM de la sous-requête.

    INSERT INTO dossier
    (idDossier, numero, heure_creation, jour_creation, mois_creation, annee_creation)
    VALUES
    (null, COALESCE(
    select maxnum from
    (SELECT MAX(numero) as maxnum FROM dossier WHERE annee_creation = '2006') as Tmp
    ) + 1, 1 ), '23:25:9', '30', '12', '2006');

    Ça a l'air complètement idiot, mais en fait MySQL va implémenter TMP à travers une table temporaire.
    Antoun
    Expert Essbase, BO, SQL

    La bible d'Essbase, 2ème édition

  10. #10
    Membre à l'essai
    Inscrit en
    Décembre 2006
    Messages
    18
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 18
    Points : 13
    Points
    13
    Par défaut
    Effectivement c'est plutôt tordu
    Comme dirait l'autre, "il faut le savoir"...

    Merci en tous cas pour ce coup de main !

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

Discussions similaires

  1. [AC-2007] Gérer une année automatiquement pour déduire une date
    Par tibofo dans le forum VBA Access
    Réponses: 8
    Dernier message: 16/07/2010, 19h47
  2. Réponses: 1
    Dernier message: 22/02/2006, 09h02
  3. [dbase] Possibilité de gèrer une base via c++?
    Par WriteLN dans le forum C++
    Réponses: 6
    Dernier message: 08/11/2004, 17h27
  4. Gérer une barre d'outils
    Par Jean Claude BOULET dans le forum Access
    Réponses: 2
    Dernier message: 07/10/2004, 22h54
  5. [ODBC][WINDOWS] gérer une base via ODBC
    Par narmataru dans le forum Windows
    Réponses: 2
    Dernier message: 19/12/2003, 13h36

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