Clé primaire avec numéro séquentiel préfixé... - SQL/NoSQL - Programmation
Marsh Posté le 14-03-2006 à 17:46:50
Je suis loin d'être calé mais dans ton cas :
- je me dirais que c'est assez tordu de choisir une clé primaire comme celle-ci.
- je bidouillerai mes insertions de la manière qui va suivre.
Je décline toute responsabilité quand à la "goret attitude" qui pourrait découler de mon message.
J'utilise la syntaxe MySQL mais l'équivalent devrait exister de ton côté.
Insert into matable (`cle_primaire`) values ([select ci-joint])
c'est là que c'est moche et largement optimisable je pense.
Je décompose.
On va faire une concaténation de deux choses :
- le couple année-mois.
- l'id_max de la période en cours + 1.
Ca va nous donner année-mois-(id_max+1)
Sous MySQL la fonction now() permet de récupérer la date et l'heure courante.
Associé à DATE_FORMAT et un masque de saisie, on a déjà la moitié du boulot de fait :
SELECT DATE_FORMAT( now( ) , '%y-%m' ) |
Pour la suite c'est un peu plus lourd.
On commence par lister les id pour le mois et l'année en cours.
La fonction LEFT permet de conserver les 5 caractères en partant de gauche (année-mois) pour effectuer notre tri.
On sélectionne la partie id avec RIGHT:
Select RIGHT(`cle_primaire`,4) |
Ce qui nous interesse c'est l'id_max donc on repasse une couche, le casting vers binary est peut être pas le meilleur choix.
SELECT MAX( CAST( RIGHT( `cle_primaire` , 4 ) AS BINARY ) ) |
Le soucis c'est que si pour année-mois en cours il n'y a pas d'enregistrement, tu te retrouve avec NULL. ca se corrige avec la fonction coalesce(découverte sous peu, jsuis fan ), je lui file 1 en paramètre.
En fait coalesce analyse chaque paramètre et renvoie le premier qui est non nul donc 1 dans notre cas.
Dernier détail, il faut ajouter 1 à noter id_max sinon on se retrouve avec un doublon:
|
Au final :
select DATE_FORMAT(now(),'%y-%m'), |
Tu remarqueras que cette requête n'est pas prête à être inserée dans
Insert into matable (`cle_primaire`) values ([select ci-joint]).
Je n'ai pas réussi à faire ma concaténation (problème de casting je pense). De plus, il faut "générer" les '0' manquants car ce select va sortir :
06-03 1
au lieu de
06-03 0001
Voilà un début de piste mais bon encore une fois, c'est bête de devoir réinventer la roue quand l'autoincrement fait ca très bien ...
Marsh Posté le 14-03-2006 à 15:46:23
Hello ,
Je reprends un projet en cours de développement et j'ai un point qui ne me semble pas très clair.
Le but est de créer une clef primaire composée des deux derniers chiffres de l'année en cours + les chiffres du mois en cours + numéro séquentiel.
Exemple : 06-03-0114
Le "numéro séquentiel" doit s'initialiser à chaque changement de mois, ainsi le premier enregistrement du mois prochain devrait-être le "06-03-0001"
Je doute fort qu'une base de données (je travaille ici sous Informix) puisse gérer "automatiquement" et toute seule ces données et les gérer par code me semble assez risquer pour une application extranet.
Avez-vous un retour d'expérience ou une réponse efficace au sujet de ce genre de chose?
Merci beaucoup.
Michel