[RESOLU][ORACLE] Sequence - Probleme avec les nombres générés

Sequence - Probleme avec les nombres générés [RESOLU][ORACLE] - SQL/NoSQL - Programmation

Marsh Posté le 25-06-2008 à 10:23:22    

Slt,
 
j'utilise une sequence pour remplir le champ "empno", clé primaire d'une table d'information d'employée.
 

Code :
  1. create sequence SEQ_NO_EMPLOYEE
  2. minvalue 1
  3. maxvalue 999999999999999999999999999
  4. start with 1
  5. increment by 1
  6. cache 20;


 
J'utilise ensuite un job qui execute quotidiennement la procedure suivant pour mettre a jour les données d'employees ou pour ajouter les nouveaux employee:
 

Code :
  1. CREATE OR REPLACE PROCEDURE sp_CXDD_CEDD_Update_or_Add
  2. IS
  3. BEGIN
  4.  
  5.     MERGE INTO t_cedd_main M
  6.           USING (SELECT * FROM t_cedd_main_temp) T
  7.              ON (M.PersonIdNo = T.PersonIdNo)
  8.         WHEN MATCHED THEN
  9.         UPDATE SET
  10.                 M.FirstName = T.FirstName, .....
  11.     WHEN NOT MATCHED THEN
  12.           -- New Employee.
  13.           INSERT
  14.            (
  15.               M.EmpNo, M.PersonIdNo, ....
  16.            )
  17.            VALUES
  18.            (
  19.               Seq_No_Employee.NextVal, ....       
  20.            );
  21.          
  22.            COMMIT;
  23.          
  24.        EXCEPTION
  25.          WHEN DUP_VAL_ON_INDEX THEN
  26.             ROLLBACK;
  27.                
  28. END sp_CXDD_CEDD_Update_or_Add;


 
J'ai un soucis avec ma sequence, car apres chaque execution de cette procedure, bien qu'aucun employee ne soit mise à jour ou ajouté dans la table j'ai ma séquence qui est incrémentée. Conséquence de ceci, c'est qu'apres 3 executions de cette stored procedure, le "NextVal" de ma sequence est à déjà plus de 20000! Sachant que ma stored procedure doit etre executé tous les jours, j'imagine pas la valeur générer au bout d'un mois :S
 
Comment incrementer le numero de sequence que lors d'un insert et évizer de se retouver avec de si grand nombre générer?
 
A+


Message édité par cervantes le 02-07-2008 à 15:46:53
Reply

Marsh Posté le 25-06-2008 à 10:23:22   

Reply

Marsh Posté le 25-06-2008 à 10:59:10    

ne pas incrémenter ta séquence ou utiliser la valeur courante si tu n'as aucun besoin de l'incrémenter

Reply

Marsh Posté le 25-06-2008 à 11:30:26    

Desolé jai pas compris ce que tu veux dire. Si je n'incremente pas la sequence, elle ne me sert à rien si je veux un numero unique pour chaque employee unique  :??: Par ailleurs si j'utilise juste CurrVal, je me retrouve avec "CURRVAL is not yet defined in this session"


Message édité par cervantes le 25-06-2008 à 11:31:00
Reply

Marsh Posté le 01-07-2008 à 18:57:09    

tu veux dire que ta séquence s'incrémente même lorsqu'il ne passe pas dans le "when not match" ???
 
étrange. ça donne quoi si tu tentes de fait un dbms.output dans ton "when not match" ?

Reply

Marsh Posté le 01-07-2008 à 23:53:22    

En fait je ne peux pas t'affirmer qu'elle s'incremente aussi quand je suis pas dans le "when not match", mais ce que je peux te dire c'est que la "Next value" est à 13000, qques chose comme ca apres la premiere execution.

 

Je refais des tests demain.
Merci pour la reponse.
++


Message édité par cervantes le 01-07-2008 à 23:53:41
Reply

Marsh Posté le 02-07-2008 à 09:37:31    

Alors rectification, jai effacé toute la table et reexecuter mon job (qui appel la procedure mise dans mon premier post). Pour 9592 entrée dans la table, la sequence a comme prochaine value 9601, donc déjà il y a un probleme là.
Ensuite, apres une deuxieme execution le "Next number" est à 19201.  :ouch: Sachant que normalement ca devrait toujours etre à 9592 vu qu'il n'y a pas de nouveau employé ni de mise à jour à faire.
Troisieme execution, "Next number" est à 28781.  :cry:  
 
J'ai mis un DBMS_OUTPUT.PUT_LINE('This is a test'); apres le Insert dans le when not match, mais jai rien sur la sortie.

Reply

Marsh Posté le 02-07-2008 à 10:15:18    

T'est sûr que t'as pas un trigger ou autre connerie qui traîne ?
Parceque là c'est très étrange quand même...
 
Crée une seconde séquence bidon, et utilise-là dans ta PS au lieu d'appeler l'actuelle, voir si c'est bien ta PS qui incrémente le compteur...
 
Parceque si ton code c'est juste ce que t'as posté, pour moi y'a un bon gros bug des familles d'Oracle... Et il est tellement énorme... que j'ai du mal à y croire.

Reply

Marsh Posté le 02-07-2008 à 10:16:36    

(juste comme ça, t'appelles pas ta séquence dans le update ?)

Reply

Marsh Posté le 02-07-2008 à 10:38:14    

Re,

 

Alors apres verification, non jai pas fait l'erreur d'appeler 2 fois ma sequence dans la procedure. La sequence semble aussi bien utilisée que par une seule procedure puisqu'avec PL/SQL Developer, si je regarde dans "Referenced by" sous Sequences -> Ma_Sequence, et bien il y a seulement que ma procedure référencée.

 

Je pense que jai du faire une erreur dans le code, si les sequence étaient "buggée" sous oracle, ca se serait.

Message cité 1 fois
Message édité par cervantes le 02-07-2008 à 10:38:33
Reply

Marsh Posté le 02-07-2008 à 10:53:34    

MagicBuzz a écrit :


Crée une seconde séquence bidon, et utilise-là dans ta PS au lieu d'appeler l'actuelle, voir si c'est bien ta PS qui incrémente le compteur...


seconde sequence créée et utilisée a la place de l'autre, je me retrouve avec les memes valeur de sequence: 9601, 19201, 28781...
Sinon concernant le  
 
# EXCEPTION
#          WHEN DUP_VAL_ON_INDEX THEN
#             ROLLBACK;
 
jsuis pas sur que l'exception soit bonne, je l'ai viré pour les tests mais ca ne change rien à la sequence.

Reply

Marsh Posté le 02-07-2008 à 10:53:34   

Reply

Marsh Posté le 02-07-2008 à 11:10:51    

cervantes a écrit :


Je pense que jai du faire une erreur dans le code, si les sequence étaient "buggée" sous oracle, ca se serait.

Tu n'imagines pas le nombre de trucs apparemment sains sous Oracle qui en fait sont buggés à mort, à commencer par Oracle lui même [:ddr555]
bon sinon pour ton souci : t'aurais pas un trigger qui fout la merde quelque part ? essaie de faire un SELECT SEQ_NO_EMPLOYEE.NextVal FROM Dual, pour voir la prochaine valeur immédiatement disponible après ton insert


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 02-07-2008 à 11:26:13    

Code :
  1. SQL> SELECT SEQ_NO_EMPLOYEE.NextVal FROM Dual;
  2.    NEXTVAL
  3. ----------
  4.      19189
  5. SQL> exec sp_CXDD_CEDD_update_or_add;
  6. PL/SQL procedure successfully completed
  7. SQL> SELECT SEQ_NO_EMPLOYEE.NextVal FROM Dual;
  8.    NEXTVAL
  9. ----------
  10.      28782


 
Sinon, pour ecarter toute ambiguité sur les sequences buggées ou non sur Oracle (j'utilise pourtant une version recente: 10gR2), y a t-il une autre facon d'incrementer un champ de type integer, enfin un truc qui remplace les seqences?
 
Avant d'utiliser une sequence, javais penser faire une fonction du type, pour chaque new insert, je recupere avec un select sur la table pour avoir la plus grande valeur dans ma colonne "empno" et je l'incremente de 1. J'ai laisse cette idée des que je suis tombé sur les sequences.


Message édité par cervantes le 02-07-2008 à 11:30:18
Reply

Marsh Posté le 02-07-2008 à 12:18:38    

Mettre ton appelle à la séquence dans un trigger qui se trouve sur le "BEFORE INSERT" de ta table.
 
C'est comme ça qu'on fait habituellement.
 
Comme ça lors de l'insertion, tu laisse le champ à vide (ou avec une valeur bidon s'il est NOT NULL) et la séquence s'incrémentera automatiquement à chaque insertion de ligne, avec (et surtout) l'assurance totale que tu y fais toujours appel.
 
A froid, je dirais qu'Oracle est très con, et estime que ce serait bien de connaître le nextval même s'il n'entre pas dans ton when.
 
En passant par le trigger, à moins qu'Oracle décide d'insérer des lignes tout seul, il n'y aura plus de problème.
 
En tout cas, pour moi il s'agit clairement d'un bug d'Oracle (peut-être voulu ceci dit)


Message édité par MagicBuzz le 02-07-2008 à 12:19:25
Reply

Marsh Posté le 02-07-2008 à 12:21:48    

ça devrait donner un truc de ce genre :

Code :
  1. CREATE TRIGGER t_matable_pk
  2. before INSERT ON matable FOR each row
  3. begin
  4.   SELECT seq_matable_pk.NEXTVAL INTO :new.x FROM dual;
  5. end;

Reply

Marsh Posté le 02-07-2008 à 15:46:31    

C'est exactement ca. Avec un trigger et en supprimant dans la commande insert le nextval de la sequence, jai une bonne autoincrementation.
Restera l'interrogation sur pourquoi ma premiere implementation ne marche pas.
 
Merci bien MagicBuzz  :jap:  
 :hello:

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed