Problème PL/SQL Si tuple déjà dans la base

Problème PL/SQL Si tuple déjà dans la base - SQL/NoSQL - Programmation

Marsh Posté le 17-11-2009 à 13:48:43    

Bonjour à tous, j'ai un problème que je n'arrive pas à résoudre.
J'insère des tuples dans une table que je nomme test mais le problème et que je ne veux pas insérer un tuple qui est déjà dans la base test. Et je ne peux pas utiliser de distinct dans le SELECT, car je dois vérifier chaque tuples.  
La section DECLARE est bien déclarée ne vous en faites pas.
 

Code :
  1. BEGIN
  2. Open c1;
  3. FETCH c1 INTO lu_nomusu, lu_nompat, lu_prenom, lu_dtenai, lu_depcol, lu_motdep;
  4. co_nomusu := lu_nomusu;
  5. co_nompat := lu_nompat;
  6. co_prenom := lu_prenom;
  7. co_dtenai := lu_dtenai;
  8. co_depcol := lu_depcol;
  9. co_motdep := lu_motdep;
  10.   LOOP
  11.        FETCH c1 INTO lu_nomusu, lu_nompat, lu_prenom, lu_dtenai, lu_depcol, lu_motdep;
  12.        IF lu_nompat = co_nompat AND lu_prenom = co_prenom AND lu_dtenai = co_dtenai THEN
  13.          IF lu_depcol IS NULL AND co_depcol IS NULL THEN
  14.            INSERT INTO ANOMALIE VALUES
  15.              (
  16.              lu_nomusu, lu_nompat, lu_prenom, lu_dtenai, lu_depcol, lu_motdep
  17.              );
  18.            INSERT INTO ANOMALIE VALUES
  19.              (
  20.              co_nomusu, co_nompat, co_prenom, co_dtenai, co_depcol, co_motdep
  21.              );
  22.          END IF;
  23.          IF lu_depcol IS NULL THEN
  24.            ins_nomusu := lu_nomusu;
  25.            ins_nompat := lu_nompat;
  26.            ins_prenom := lu_prenom;
  27.            ins_dtenai := lu_dtenai;
  28.            ins_depcol := lu_depcol;
  29.            ins_motdep := lu_motdep;
  30.          ELSE
  31.            IF lu_depcol > co_depcol AND co_depcol IS NOT NULL THEN
  32.              ins_nomusu := lu_nomusu;
  33.              ins_nompat := lu_nompat;
  34.              ins_prenom := lu_prenom;
  35.              ins_dtenai := lu_dtenai;
  36.              ins_depcol := lu_depcol;
  37.              ins_motdep := lu_motdep;
  38.            END IF;
  39.          END IF;
  40.        ELSE
  41.          IF /* Si pas dans la table */ THEN
  42.            INSERT INTO UNEFOIS VALUES          
  43.            (
  44.            ins_nomusu, ins_nompat, ins_prenom, ins_dtenai, ins_depcol, ins_motdep
  45.            );
  46.          END IF;
  47.        END IF;
  48.        co_nomusu := lu_nomusu;
  49.        co_nompat := lu_nompat;
  50.        co_prenom := lu_prenom;
  51.        co_dtenai := lu_dtenai;
  52.        co_depcol := lu_depcol;
  53.        co_motdep := lu_motdep;
  54.        EXIT WHEN c1%NOTFOUND;
  55.    END LOOP;
  56.    CLOSE c1;
  57. END;


 
Merci à tous.


Message édité par MaRTy59 le 17-11-2009 à 14:26:41
Reply

Marsh Posté le 17-11-2009 à 13:48:43   

Reply

Marsh Posté le 17-11-2009 à 14:10:24    

solution 1 un peu de porc: mettre une pk ou un index unique sur ta clé et gérer cela dans un bloc d'exception sur le bon errcode.
 
pour les autres solutions mets au moins la balise code=sql que l'on ne s'arrache pas les yeux a comprendre tes imbrications, et d'autre part je ne comprend pas tes affectations qui pour moi n'ont aucun impact (ligne 24 a 37)

Reply

Marsh Posté le 17-11-2009 à 14:35:04    

En fait je dois faire attention à une date de la ligne 24 à 37, parmis tous les doublons je dois trouver une anomalie, si depcol est null (champ date) alors je sauvegarde les champs du tuple lu, sur l'itération suivante je regarde si par rapport au tuple d'avant, la personne est identique, si oui alors je regarde la date, si elle est encore null je sauvegarde les deux, si le champ depcol est rempli alors je compare avec l'ancien tuple sauvegarder. Et je prends la plus récente des deux et ainsi de suite.

Reply

Marsh Posté le 17-11-2009 à 14:50:35    

il n'y a pas 30000 solutions,  

  • soit mettre une contrainte et attendre que ca pete dans un bloc d'exception
  • soit faire un merge or insert si tu peux te permettre un update
  • soit tester si un record similaire existe avant ton insert

Reply

Marsh Posté le 17-11-2009 à 15:01:17    

D'accord, et comment je peux faire pour tester si un record similaire existe avant l'insert ?

Reply

Marsh Posté le 17-11-2009 à 15:11:37    

select variable := count(id)
from latableenquestion
where ...
 
tu regardes la valeur de variable, si elle est > 0 tu as déjà une valeur insérée...
 
en transactSQL il y a l'instruction if exists, je sais jamais si elle existe aussi sous Oracle ou pas :D

Reply

Marsh Posté le 17-11-2009 à 15:27:22    

Y'a pas de IF EXISTS sous Oracle, c'est dommage parce que c'est vraiment pratique :/


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

Marsh Posté le 17-11-2009 à 15:34:21    

Arf :(

Reply

Marsh Posté le 17-11-2009 à 15:47:21    

Du coup t'es bon pour un select count() dans une variable, et un if classique ensuite. Ca change pas grand-chose.

Reply

Marsh Posté le 17-11-2009 à 15:53:30    

ce n'est pas possible de faire comme tu dis car je sauvegarde plusieurs personne dans la base, avec ce que tu as je pense que apres une insertion je ne pourrais plus rien faire.

Reply

Marsh Posté le 17-11-2009 à 15:53:30   

Reply

Marsh Posté le 17-11-2009 à 15:56:39    

Hum j'avoue avoir du mal à bien saisir.  
 
Si tu dois insérer (A, B, C, D), qu'est-ce qui t'empêche d'insérer B après A ? (fonctionnellement hein)

Reply

Marsh Posté le 17-11-2009 à 15:59:56    

Je vais re-expliquer ;)
En fait je dois détecter les anomalies dans une base, elle est constituée de plusieurs personnes, ces personnes ont des dates (depcol) qui doivent être obligatoirement renseignées, or ici, les dates ne sont pas tout le temps mises. Mais une même personne peut être aussi plusieurs fois dans la base. Si une même personne y est trois fois par exemple et que dans les trois cas, seulement deux dates (depcol) sont renseignées alors je prends celle qui n'est pas renseignée. Si dans les trois cas, les trois sont renseignées, alors je prends la date la plus récente, si dans les trois cas, deux ne sont pas renseignées je prends les deux non renseignées ...
 
Jeu de test :
 
CODCOL|CODAGT|NOMPAT|PRENOM|DTENAI|DEPCOL
 
59350|12765|BER|JP|02/05/1950|NULL --> OK je ne prends pas
59350|6614|CHE|ER|01/09/1962|30/08/1990 --> OK je ne prends pas
59350|6614|CHE|ER|01/09/1962|19/10/2002 --> Vu qu'ils sont identiques je prends ce tuple ci car date plus récente que l'autre(19/10/2002 > 30/08/1990).
59350|28365|DEU|ROM|06/11/1987|30/06/2002 --> OK je ne prends pas
59350|28365|DEU|ROM|06/11/1987|NULL --> Je prends ce tuple car Il existe deux fois, sur les deux je prends la date non renseignée.
59350|22733|PI|NI|08/09/1980|NULL --> La c'est délicat c'est comme le premier tuple donc normalement on ne prends pas
59350|22733|PI|NI|08/09/1980|NULL --> Vu qu'il existe deux fois on prends les deux.  
 
Voila ça devrait aller mieux ?

Reply

Marsh Posté le 17-11-2009 à 16:32:28    

J'aurais tendance à dire que tu viens de nous sortir l'algo non ? Si tu fais un curseur sur les personnes, ensuite ce n'est amha plus qu'une histoire de select count() avec des instructions conditionnelles.


Message édité par Fred999 le 17-11-2009 à 16:32:59
Reply

Sujets relatifs:

Leave a Replay

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