Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1793 connectés 

  FORUM HardWare.fr
  Programmation
  SQL/NoSQL

  faire une requete sql avec incrémentation

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

faire une requete sql avec incrémentation

n°1837194
rira
Posté le 13-01-2009 à 10:25:37  profilanswer
 

Bonjour,  
Voici mon problème j'ai une table facture mes numéro de facture son du type AAAA-MM-N°chrono  
par exemple 2009-01-01 correspond a la 1er facture de Janvier 2009
Mon problème est que à chaque début de mois, je voudrais que mon numéro chrono reparte à 1 et que les autres factures se suivent  
et cela à chaque changement de mois, mon n°chrono doit repartir à 1
 
J'aimerais savoir quel requete insetion faire dans ma table facture.
Sachant que je génére toute mes factures en même temps pour le mois en cours  
donc je cherche une requete insertion qui puisse en plus s'incréménté par rapport aux autres
 
 

mood
Publicité
Posté le 13-01-2009 à 10:25:37  profilanswer
 

n°1837212
macgawel
Posté le 13-01-2009 à 10:52:22  profilanswer
 

rira a écrit :

Bonjour,  
Voici mon problème j'ai une table facture mes numéro de facture son du type AAAA-MM-N°chrono  
par exemple 2009-01-01 correspond a la 1er facture de Janvier 2009
Mon problème est que à chaque début de mois, je voudrais que mon numéro chrono reparte à 1 et que les autres factures se suivent  
et cela à chaque changement de mois, mon n°chrono doit repartir à 1
 
J'aimerais savoir quel requete insetion faire dans ma table facture.
Sachant que je génére toute mes factures en même temps pour le mois en cours  
donc je cherche une requete insertion qui puisse en plus s'incréménté par rapport aux autres


 :sweat:  
Mauvaise conception, changer conception.
 
D'un point de vue purement SQL :
Si c'est possible, modifie ton truc, parce que là, tu fais quelque chose d'assez pourri :
- Si tu as un champ avec la date, tu inscris deux fois la même information.
- Et si tu n'utilises pas la date, tu pourrais (devrais) te contenter d'un incrément classique (un numéro qui augmente à chaque facture).
 
Il me semble qu'un champ clé ne devrait pas être signifiant. Or, ici, on retrouve (une partie de) la date. C'est mal.
De toute façon, il n'y a pas de solution en SQL pour faire un truc comme ça. soit ton champ est en incrément (sans l'information de date) et la BDD sait le gérer, soit il est composé aussi d'une date et la BDD ne sait pas le gérer simplement.
 
Après, si tu utilises un prgramme pour accéder à la base, ce qui est généralement le cas, tu peux le faire (c'est techniquement faisable, même si fonctionnellement non souhaitable).
Il "suffit" d'avoir ton champ NUMERO_FACTURE en alpha, et de lui injecter la valeur "AAA-MM-NUMERO" dans ta requête. Et c'est le programme qui va construire cette valeur, en augmentant "NUMERO" à chaque passage du mois et en le remettant à 1 quand on change de mois.

n°1837243
omega2
Posté le 13-01-2009 à 11:43:28  profilanswer
 

Solution très crade : Avec des bases de données comme MYSQL tu peux le faire en deux passes à conditions d'avoir une clé primaire composé d'une colonne dans laquelle tu indiques l'année-mois et d'une colonne en autoincrément.
Seul avantage : tu n'as pas à t'inquiéter des trous de numérotation et des risques de collisions.
 
Solution propre : Tu te crée une table de compteur dans lequel tu te feras un compteur par mois que tu incrémentes avant chaque insertion afin d'avoir ta partie numérique. A noter qu'il est obligatoire de mettre en place un verrou d'écriture sur cette table là (verrou sur la table entière s'il est impossible de faire un verrou sur une seule ligne) pour éviter tout risque de trou de numérotation et de numéro identique pour plusieurs factures. Ces deux cas n'ont pas le droit d'arriver car ils sont signe de fraude en cas de contrôle fiscal et les conséquences peuvent être dramatique pour la boite qui utilise le logiciel, celle qui a créé le logiciel (le client pouvant se retourner contre l'éditeur) et celui qui a développer le système de facturation (l'employeur pouvant ensuite se retourner contre le développeur)
 
Avec la seconde solution, on a ensuite le choix entre :
- tout faire dans le programme
- utiliser une procédure stocké (un petit script dans la base de donnée) qui va incrémenter le compteur et retourner la nouvelle valeur
- utiliser un trigger qui va générer le numéro de facture à partir d'une date (date courante ou date fournis dans la requête de création de facture) et de la table de compteur.
 
L'inconvénient principal du trigger c'est qu'en cas de changement de modèle de numéro de facture, il faut modifier le trigger et pas le programme. L'avantage c'est que le développeur n'a plus à se soucier de la numérotation des factures et qu'on est certain que ça marche quelque soit le programme qui rajoutera des factures.
 
PS : J'ai mis des liens vers la documentation de mysql mais c'est le même principe quelque soit la base de donnée (hors access) . Consulte donc la documentation de ta base de donnée pour plus de détail sur le fonctionnement.
 
EDIT : La même chose en plus clair.


Message édité par omega2 le 13-01-2009 à 12:06:09
n°1837245
rira
Posté le 13-01-2009 à 11:44:37  profilanswer
 

ok,  
je précise que dans ma table facture j'ai une clé primaire avec un numéro qui s'incrément automatiquement, un champ année et un champ mois ainsi qu'un champ n° chrono.
Malheureusement, je ne peux pas utiliser ma clé primaire car nous souhaiterions avoir un numéro de facture  (utiliser uniquement lors de l'affichage ainsi que par la compta) qui soit du type AAAA-MM-N°chrono qui commence à 1 et qui se suivent  
et qui recommence à 1 le mois suivant
comment faire?

n°1837262
rira
Posté le 13-01-2009 à 12:08:49  profilanswer
 

omega2 peux tu m'expliquer plus précisement ta solution propre?

n°1837263
omega2
Posté le 13-01-2009 à 12:09:04  profilanswer
 

Ben dans ce cas, tu n'as pas le choix : il faut que tu fasse une table de compteur (id autocrémenté, nom de compteur (pour pouvoir réutiliser la table pour d'autres compteurs) , indice (le mois pour cette table) et valeur (nombre à incrémenter à chaque demande) )
 
Pour les détails, voir le message ci-dessus que j'ai édité en espérant que c'est plus clair.

n°1837269
rira
Posté le 13-01-2009 à 12:24:12  profilanswer
 

merci je vais regarder avec cela  
malheureusement je suis sous Access, donc je vais essayé de ruser

n°1837275
omega2
Posté le 13-01-2009 à 12:34:37  profilanswer
 

Access dispose de quoi faire des verrous. Par contre je ne peux pas t'en dire plus : j'évite autant que possible d'utiliser access.

n°1837276
macgawel
Posté le 13-01-2009 à 12:52:57  profilanswer
 

rira a écrit :

je précise que dans ma table facture j'ai une clé primaire avec un numéro qui s'incrément automatiquement, un champ année et un champ mois ainsi qu'un champ n° chrono.


rira a écrit :

malheureusement je suis sous Access


Donc, tu dois avoir un masque de saisie pour ta facture.
Deux solutions :
 
1. solution "propre" mais lourde :
- Tu crées une table FacturesMois -> Annee_mois | Numero
- Quand tu valides la facture, Avant de l'insérer (il doit y avoir un évènement Before_Insert), tu prends le FactureMois.NUMERO correspondant à AAA-MM pour le mettre dans ton Num_Chrono et tu fais un UPDATE FactureMois.NUMERO =  FactureMois.NUMERO + 1.
C'est lourd, et ce n'est pas si propre que ça je trouve  :kaola:  
 
2. Solution Quick and Dirty, vu que tu saisis toutes les factures du mois en un coup :
- A l'ouverture de ton "application" ou à la modification du mois de facturation, tu initialises une variable ChronoMois = 1
- A la création d'une facture, tu mets ChronoMois dans le champ NUM_CHRONO.
- A l'insertion de la facture tu augmentes la valeur de ta variable ChronoMois.
 
3. solution un peu moins crade, qui te permet de saisir les factures en plusieurs fois :
- Suivant le fonctionnement de ton appli, quand tu crées une facture ou quand tu renseigne le mois de la facture, tu fais un SELECT MAX(Facture.NUM_CHRONO) WHERE Facture.ANNEE = VarAnnee AND Facture.MOIS = VarMois.
- Tu mets cette valeur dans une variable VarDerniereFacture
- Quand tu crées une facture (ou quand tu renseigne le mois, ou quand tu fais l'insert...) tu mets la valeur VarDerniereFacture + 1 dans ton champ Facture.NUM_CHRONO
Je pense que c'est le meilleur compromis...

n°1837345
omega2
Posté le 13-01-2009 à 14:49:22  profilanswer
 

Trop lourd une table de compteur? :o Et tu penses vraiment qu'un "select max(colonne)" est plus légé?
 
Principaux défauts d'un "select max(colonne)" comparé à un compteur :
- moins propre (mélange de la notion de compteur avec celle d'une colonne dont la fonction n'a rien à voir)
- beaucoup plus lent
- impossible de faire des verrous de ligne ou de plage (obligé de verrouiller la table entière) et des verrous de modification (obligé de faire un verrou lecture/ecriture) => impossible de consulter une facture déjà existante tant que la création n'est pas terminé
- obliger de découper le numéro de facture pour en retirer la partie "compteur" afin de l'incrémenter
 
Au pire, faire un "select valeur from mescompteurs where compteur = 'AAAAMM' " avant de faire l'insertion (donc sans utiliser de trigger) est moins lourd au niveau de la base de donnée et au niveau du code de l'application que le bidouillage de débutant que tu proposes dans ton 3) .

mood
Publicité
Posté le 13-01-2009 à 14:49:22  profilanswer
 

n°1837370
MagicBuzz
Posté le 13-01-2009 à 15:11:14  profilanswer
 

par contre faut pas oublier de faire un lock sur la table compteur tout le temps de la transaction, sinon proutch ça te fait des doublons.
 
et dans tous les cas, il vaut mieux faire un trigger sur le champ ID, qui s'occupe de récupérer la valeur du compteur et l'incrémenter, ceci rends le truc transparent dans le programme (t'insères sans te soucier de l'id, comme si c'était un bête compteur standard), et ça évite de se planter de compteur quand un petit malin vient bidouiller la base à la main ou faire de la maintenance dans ton programme sans rien comprendre à ce que tu fais

n°1838775
rira
Posté le 16-01-2009 à 10:15:17  profilanswer
 

merci pour tout, me faudrais juste une petite aide sur la requete INSERT
je dois inserer tout mes facture du mois avec n° chrono +1 du précédent,
à insérer facture_client, facture_num_période, facture_chrono  
et la je vois pas trop comment la faire ...

n°1838912
skeye
Posté le 16-01-2009 à 13:54:26  profilanswer
 

J'ai pas lu toutes les réponses, mais il y a une raison quelconque de vraiment stocker ce numéro qui devrait être calculé et qui ne sert qu'à l'affichage?


---------------
Can't buy what I want because it's free -
n°1839035
omega2
Posté le 16-01-2009 à 16:07:43  profilanswer
 

D'un point de vue comptable, il me semble que les numéros de factures doivent toujours être non modifiable. Quoi de plus fiable qu'un stockage du numéro de facture pour éviter les problèmes?
 
PS : A la réflexion, une table de type "archive" serait idéal pour stocker ce genre d'infos vu qu'avec une telle table, on ne peut rien modifier.

n°1839070
macgawel
Posté le 16-01-2009 à 16:32:28  profilanswer
 

omega2 a écrit :

D'un point de vue comptable, il me semble que les numéros de factures doivent toujours être non modifiable. Quoi de plus fiable qu'un stockage du numéro de facture pour éviter les problèmes?
 
PS : A la réflexion, une table de type "archive" serait idéal pour stocker ce genre d'infos vu qu'avec une telle table, on ne peut rien modifier.


Si je me souviens bien :
Le numéro de facture n'est absolument pas obligatoire.
MAIS il est fortement conseillé  :D  
Et, en cas de contrôle, c'est toujours bien vu si :
- Les factures sont numérotées
- La numérotation se fait sur l'année d'exercice (au minimum)
- Les numéros se suivent sans interruption
- La numérotation est infalsifiable
 
=> Dans ce cadre :
- C'est mieux de faire un numéro de facture qui ne soit pas AAAA-MM-NUMERO mais (AAAA-)NUMERO.
- Pour la numérotation "infalsifiable", c'est plus délicat vu qu'on peut (quasiment) toujours modifier un fichier informatique. A la limite, le plus sûr, de ce point de vue, c'est d'avoir les factures sous forme papier...

n°1839843
rira
Posté le 19-01-2009 à 09:06:35  profilanswer
 

je suis obligé d'avoir un numéro chrono qui démarre à 1 en début de moi avec des numéro qui se suive car le tout sera envoyé au trésor public pour vérification donc avec un controle des num° de facture qui se suivent

n°1839855
macgawel
Posté le 19-01-2009 à 09:48:42  profilanswer
 

rira a écrit :

je suis obligé d'avoir un numéro chrono qui démarre à 1 en début de moi avec des numéro qui se suive car le tout sera envoyé au trésor public pour vérification donc avec un controle des num° de facture qui se suivent


Au Trésor Public ?
 
Tu devrais vérifier, parce que :
- Je ne vois pas trop pourquoi le TP ferait des vérifiactions de factures ?
- Je ne suis pas sûr qu'une numérotation "mensuelle" leur convienne.

n°1839876
couak
Posté le 19-01-2009 à 11:02:52  profilanswer
 

si si c'est vrai, pareil pour le comptable, et vaut mieux faire comme demande le trésor public si on ne veut pas un contrôle fiscal
ce sont des gens assez bornés

n°1839878
omega2
Posté le 19-01-2009 à 11:07:33  profilanswer
 

couak a écrit :

ce sont des gens assez bornés

Pas tous, à ce qu'il parait les pire sont les nouveaux qui doivent faire leur preuves et ceux qui sont proche de la retraite.
 
En même temps, c'est quand même leur boulot de tout vérifier et le meilleur moyen de leur montrer qu'on ne cache rien, c'est d'avoir des systèmes de numérotation infalsifiable (aucun trou ni doublon dans la numérotation et aucune "astuce" dans les logiciels qui permette de modifier les numéros ou de supprimer des éléments).

n°1840063
MagicBuzz
Posté le 19-01-2009 à 16:20:49  profilanswer
 

euh... un champ "identity" ça me semble quand même plus fiable qu'un compteur perso, c'est infalsifiable, y'a pas de trou, et voilà quoi...


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  SQL/NoSQL

  faire une requete sql avec incrémentation

 

Sujets relatifs
Requete GROUP BY ou DISTINCT ou impossible a faire ?[MYSQL] Aide pour une requête
[ACCESS] Problème requête et valeur par défaut[SQL] Requete Group By en prenant les infos du plus petit
AS2 temporiser l'incrémentation dans une boucleAccess - requete pour regrouper plusieurs champs en 1 seul
Requète Access[ Resolu ] Ma requete ne fonctionne qu'à moité ! Avez-vous une idée ?
[MS Access] Requete sur horodatage "flou"Requête en jointure
Plus de sujets relatifs à : faire une requete sql avec incrémentation


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR