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) from matable where LEFT( `cle_primaire` , 5 ) = DATE_FORMAT( now( ) , '%y-%m' ) |
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 ) )
FROM matable
WHERE LEFT( `cle_primaire` , 5 ) = DATE_FORMAT( now( ) , '%y-%m' ) |
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:
SELECT MAX( 1 + coalesce( CAST( RIGHT( `cle_primaire` , 4 ) AS BINARY ) ,1) )
FROM matable
WHERE LEFT( `cle_primaire` , 5 ) = DATE_FORMAT( now( ) , '%y-%m' ) |
Au final :
select DATE_FORMAT(now(),'%y-%m'),
MAX(1+coalesce(CAST(RIGHT(`cle_primaire`,4) as BINARY),1)) from matable where LEFT(`cle_primaire`,5)=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 ...
Message édité par jeoff le 14-03-2006 à 17:52:57