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

  FORUM HardWare.fr
  Programmation
  SQL/NoSQL

  PL/SQL Utilisation de cursor

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

PL/SQL Utilisation de cursor

n°1237238
lapartdomb​re
Posté le 03-11-2005 à 10:56:38  profilanswer
 

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
mood
Publicité
Posté le 03-11-2005 à 10:56:38  profilanswer
 

n°1237264
Beegee
Posté le 03-11-2005 à 11:26:01  profilanswer
 

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
n°1237320
lapartdomb​re
Posté le 03-11-2005 à 11:55:42  profilanswer
 

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??

n°1237337
Beegee
Posté le 03-11-2005 à 12:08:53  profilanswer
 

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
n°1237352
lapartdomb​re
Posté le 03-11-2005 à 12:15:52  profilanswer
 

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

n°1237389
lapartdomb​re
Posté le 03-11-2005 à 12:36:21  profilanswer
 

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é

n°1237435
Beegee
Posté le 03-11-2005 à 13:43:08  profilanswer
 

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

n°1237505
lapartdomb​re
Posté le 03-11-2005 à 14:17:20  profilanswer
 

ca ne change rien

n°1237556
Beegee
Posté le 03-11-2005 à 14:40:30  profilanswer
 

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
n°1238371
orafrance
Posté le 04-11-2005 à 08:01:46  profilanswer
 

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


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

  PL/SQL Utilisation de cursor

 

Sujets relatifs
Base SQL trop grosse pour l'importée...Requete SQL
[SQL/Windev] INTO OutfileSauvegarde base SQL
SQL loader probleme[SQL - ORACLE] Requete un peu complexe (pour moi)
[SQL] pb de selection...Comment faire cette requête SQL avec des combinaisons
[VB.NET/Mysql] Utilisation de MysqlConnectorUtilisation de fichier *.hta
Plus de sujets relatifs à : PL/SQL Utilisation de cursor


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