PL/SQL Utilisation de cursor

PL/SQL Utilisation de cursor - SQL/NoSQL - Programmation

Marsh Posté le 03-11-2005 à 10:56:38    

Je cherche à copier une table dans une autre. Pour chaque enregisrement je veux vérifier que le code de l'enregistrement est contenu dans la table de destination. S'il est bien contenu, je vais un update de la ligne sinon je dois refusé l'importation de la ligne et loggé l'erreur.
Mon problème c'est que mon update ne se déclenche jamais et je ne sais pas comment faire pour logger l'information en cas de refus d'importation.
 

Code :
  1. DECLARE 
  2.  
  3.   TYPE recordTypeFlux IS RECORD
  4.     (
  5.       libelle tmp_type_flux.tf_libelle%TYPE,
  6.       code tmp_type_flux.tf_code%TYPE
  7.     );
  8.   rec recordTypeFlux;
  9.  
  10.   CURSOR CurseurTypeFlux IS select tf_libelle , tf_code from tmp_type_flux;
  11.   CURSOR ExisteTypeFlux IS select * from type_flux where type_flux.code_type_flux = rec.code;
  12.      
  13. BEGIN 
  14.   OPEN CurseurTypeFlux;
  15.   OPEN ExisteTypeFlux; 
  16.   dbms_output.put_line('1');
  17.  
  18.   LOOP 
  19.     FETCH CurseurTypeFlux INTO rec;
  20.       EXIT WHEN CurseurTypeFlux%NOTFOUND;
  21.      
  22.     If ExisteTypeFlux%NOTFOUND Then
  23.       update type_flux set libelle_type_flux = rec.libelle;
  24.       /* insert into type_flux(libelle_type_flux, code_type_flux) values (rec.libelle,rec.code); */
  25.     END If;
  26.    
  27.   END LOOP;
  28.   CLOSE CurseurTypeFlux;
  29.   CLOSE ExisteTypeFlux;
  30.   COMMIT;
  31. END;


Message édité par lapartdombre le 03-11-2005 à 11:05:26
Reply

Marsh Posté le 03-11-2005 à 10:56:38   

Reply

Marsh Posté le 03-11-2005 à 11:26:01    

Le 2nd curseur utilise la variable rec, remplie par le résultat du 1er curseur.
Il faut peut-être que tu fasses un OPEN / FETCH du 2ème curseur juste avant de regarder %NOTFOUND.
Et enfin, je comprends pas trrop ta logique ! Quand le code n'est pas trouvé dans type_flux, tu mets à jours TOUS les libellés de type_flux !!!
J'imagine que tu veux mettre à jour le libellé dans type_flux, à code égal, trouvé dans tmp_type_flux.
 
Voici un moyen de le faire, plus simple :
 

Code :
  1. DECLARE
  2.   numberOfRowsMissing INTEGER;
  3. BEGIN
  4.   -- Verification de la coherence des donnees entre tmp_type_flux et type_flux
  5.   SELECT COUNT(*)
  6.   INTO numberOfRowsMissing
  7.   FROM tmp_type_flux ttf
  8.   WHERE NOT EXISTS (SELECT 1 FROM type_flux tf WHERE tf.code = ttf.code);
  9.   IF (numberOfRowsMissing > 0) THEN
  10.     RAISE_APPLICATION_ERROR(-20000, 'La table tmp_type_flux contient ' || numberOfRowsMissing  || ' lignes  qui n'existent pas dans type_flux');
  11.   END IF;
  12.   -- Mise à jour de type_flux
  13.   FOR r IN (
  14.     SELECT code, libelle
  15.     FROM tmp_type_flux
  16.   )
  17.   LOOP
  18.     UPDATE type_flux
  19.     SET libelle = r.libelle
  20.     WHERE code = r.code;
  21.   END LOOP;
  22. END;


 
edit : si tu veux plutôt sortir un message d'erreur (dbms_output) par ligne manquant, il faut faire le COUNT dans la boucle plutôt, voire faire l'UPDATE et récupérer le nombre de lignes affectées (il me semble qu'on peut récupérer l'info).

Message cité 1 fois
Message édité par Beegee le 03-11-2005 à 11:36:52
Reply

Marsh Posté le 03-11-2005 à 11:55:42    

Beegee a écrit :


edit : si tu veux plutôt sortir un message d'erreur (dbms_output) par ligne manquant, il faut faire le COUNT dans la boucle plutôt, voire faire l'UPDATE et récupérer le nombre de lignes affectées (il me semble qu'on peut récupérer l'info).


 
Ca marche beaucoup mieux de ta facon et c'est beaucoup moins compliqué. En fait il faudrait que je mette un message d'erreur dans un fichier de log quand le code que je recherche n'est pas présent dans la table. Est ce que tu sais comment faire??

Reply

Marsh Posté le 03-11-2005 à 12:08:53    

Code :
  1. DECLARE
  2.   numberOfRowsUpdated INTEGER;
  3.   fileHandler UTL_FILE.FILE_TYPE;
  4. BEGIN
  5.   -- Ouverture du fichier de log
  6.   fileHandler := UTL_FILE.FOPEN('/tmp', 'myfile', 'w');
  7.   -- Verification de la coherence des donnees entre tmp_type_flux et type_flux
  8.   FOR r IN (
  9.   SELECT ttf.code, ttf.libelle
  10.   FROM tmp_type_flux ttf
  11.   WHERE NOT EXISTS (SELECT 1 FROM type_flux tf WHERE tf.code = ttf.code)
  12.   )
  13.   LOOP
  14.     UTL_FILE.PUTF(fileHandler, 'La ligne de tmp_type_flux contenant le code: ' || r.code || ' et le libellé : ' || r.libelle || ' ne correspond à aucune ligne de type_flux');
  15.   END LOOP;
  16.   -- Mise à jour de type_flux (si le code n'existe pas dans type_flux, l'UPDATE ne fera rien)
  17.   FOR r IN (
  18.     SELECT code, libelle
  19.     FROM tmp_type_flux
  20.   )
  21.   LOOP
  22.     UPDATE type_flux
  23.     SET libelle = r.libelle
  24.     WHERE code = r.code;
  25.   END LOOP;
  26.   -- Fermeture du fichier de log
  27.   UTL_FILE.FCLOSE(fileHandler);
  28. EXCEPTION
  29.   WHEN utl_file.invalid_path THEN
  30.     RAISE_APPLICATION_ERROR(-20000, 'Erreur: répertoire / nom de fichier invalide');
  31. END;


Message édité par Beegee le 03-11-2005 à 12:10:55
Reply

Marsh Posté le 03-11-2005 à 12:15:52    

Super merci beaucoup... je crois que c'est ca qui me manquait un fichier d'exemple

Reply

Marsh Posté le 03-11-2005 à 12:36:21    

J'ai encore une petite question, j'ai repris ton exemple et j'ai modifié en
 

Code :
  1. -- Ouverture du fichier de log
  2.    fileHandler := UTL_FILE.FOPEN('D:/log', 'copie.log', 'w');


 
Mais j'ai un message d'erreur comme quoi  ORA-20000: Erreur: répertoire / nom de fichier invalide...alors que mon fichier est bien dans le répertoire spécifié

Reply

Marsh Posté le 03-11-2005 à 13:43:08    

C'est pas plutôt "D:\" ?
 
(la commande créera le fichier)

Reply

Marsh Posté le 03-11-2005 à 14:17:20    

ca ne change rien

Reply

Marsh Posté le 03-11-2005 à 14:40:30    

Il faut que le fichier de configuration init.ora, utilisé pour ton instance Oracle, renseigne la valeur utl_file_dir :
 
utl_file_dir = 'D:\'
 
http://www.freelists.org/archives/ [...] 01386.html


Message édité par Beegee le 03-11-2005 à 14:40:44
Reply

Marsh Posté le 04-11-2005 à 08:01:46    

ou alors créer une DIRECTORY et l'indiquer à la place de ce chemin :)

Reply

Sujets relatifs:

Leave a Replay

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