IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

PL/SQL Oracle Discussion :

Blocs imbriqués et transmission de variable


Sujet :

PL/SQL Oracle

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    72
    Détails du profil
    Informations personnelles :
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Mai 2010
    Messages : 72
    Par défaut Blocs imbriqués et transmission de variable
    Bonjour à tous!

    J'ai beau chercher, tester, m'acharner, ça coince. Peut-être un détail, mais je coince...
    Mon problème, simplement de récupérer la valeur d'une variable d'un bloc BEGIN vers le bloc supérieur. Bon, un exemple sera plus parlant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     
    PROCEDURE import(...)
    IS
    ...
    stMsg			VARCHAR2(250);
     
     
    BEGIN
    IF action='ouverture' THEN
       ...
    ELSEIF action='lecture ligne' THEN
      BEGIN
      ... (traitements)
      if (cas1) then stMsg=stMsg || 'cas 1 présent';
      ...
      END;
     
    ELSEIF action='fermeture'
     ...
      UTL_FILE.PUTF( Rapport , stMsg);
     ...
    END;
    Vraiment résumé sur l'essentiel; le code marche (déjà en place depuis longtemps). Là le but c'est sur lecture d'une ligne si cas1 je mets un texte dans ma variale stMsg.
    A la fin du traitement, on arrive dans le esleif fermeture, je mets mes textes concaténés dans un fichier...

    Sauf que ma variable est systématiquement vide!
    Si je l'imprime dans min "if (cas1)", ça marche (enfin, il m'écrit le texte de la ligne en cours, pas une concaténation de toutes les lignes comme j'aurais pensé...ce qui veut bien dire qu'à la sortie de la boucle, ma variable ne garde pas sa valeur).

    Donc le problème est simple : il ne reste plus qu'à ne pas perdre le contenu de cette variable une fois sorti du mon BEGIN imbriqué.
    Simple... mais je coince depuis plusieurs jour!

    Merci pour votre aide!

    PS : il s'agit d'Oracle 91, si jamais ça joue...

  2. #2
    Rédacteur

    Homme Profil pro
    Consultant / formateur Oracle et SQL Server
    Inscrit en
    Décembre 2002
    Messages
    3 461
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Consultant / formateur Oracle et SQL Server

    Informations forums :
    Inscription : Décembre 2002
    Messages : 3 461
    Par défaut
    Faire +1 sur une variable VARCHAR2, c'est un peu louche !

    Et pensez à initialiser vos variables, sans quoi elles valent NULL par défaut, avec un effet absorbant lors de l'addition notamment.

    Par contre :
    NULL || '1' --> 1

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    72
    Détails du profil
    Informations personnelles :
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Mai 2010
    Messages : 72
    Par défaut
    Autant pour moi, mon code semble prêter à confusion.
    Comme dit, ce n'est pas une recopie, mais un essai de résumé.

    Et je me suis du coup planté. Je vais corriger :
    stMsg=stMsg+1;
    en
    stMsg=stMsg || 'ma seconde phrase';
    Concaténation de ma variable avec de nouveaux caractères (il s'agit de sortir le contenu de toutes les lignes souhaités dans mon fichier texte).

    Sur l'initialisation des variables, merci pour le conseil;
    j'ai d'ailleurs tenté en l'initialisant (='test'), mais le résultat n'était pas plus concluant (si : j'avais 'test' au lieu de rien... mais toujours pas les textes concaténé attendus).

  4. #4
    Rédacteur

    Homme Profil pro
    Consultant / formateur Oracle et SQL Server
    Inscrit en
    Décembre 2002
    Messages
    3 461
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Consultant / formateur Oracle et SQL Server

    Informations forums :
    Inscription : Décembre 2002
    Messages : 3 461
    Par défaut
    Le plus efficace, c'est que vous nous fournissiez une procédure minimale valide (qui compile sans erreur) et qui démontre votre problème.

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    72
    Détails du profil
    Informations personnelles :
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Mai 2010
    Messages : 72
    Par défaut
    Pourquoi pas, le voici.

    Mais fondamentalement, la question serait juste "comment récupérer une variable d'un BEGIN imbriqué vers le BEGIN "père"?

    Voici mon code tel qu'il tourne actuellement. J'ai du coup ouvert un fichier dans le BEGIN principal, et la boucle du BEGIN "fils" ajoute une ligne dans ce fichier (si c'est nécessaire).
    Pour illuster mon problème, j'ai remis le "nudebug", en gras ci dessous.
    - initialisé en début de procédure;
    - incrémenter de 100 ou de 1 suivant les cas à chaque boucle dans le begin imbriqué
    - écriture dans un fichier du résultat tout à la fin dans le begin principal
    -> résultat = 0 au lieu de 205 par exemple.


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    PROCEDURE import_INFO_WS_ASCII		(stAction 	IN VARCHAR2,
    					Imp_Param 	IN OUT CMST_READ_ASCII.Import_ParamStruct,
    					Enreg_Param 	IN OUT CMST_READ_ASCII.Enreg_ParamSTRUCT,
    					TablField 	IN CMST_READ_ASCII.FieldTabTyp,
    					nuRet 		IN OUT INTEGER,
    					nuWarning 	IN OUT INTEGER)
    IS
    	hFile		UTL_FILE.FILE_TYPE;
    	-- etat BT
       	WS_PREPARE      	NUMBER	:= 2;
       	WS_WAIT_LAUNCH  	NUMBER	:= 4;
       	WS_INPROGRESS   	NUMBER	:= 5;
       	WS_CLOSED       	NUMBER	:= 6;
       	dtDTTM_IN_PROGRESS	DATE;
        Rapport	UTL_FILE.FILE_TYPE ;
        stRap VARCHAR2(10000);
    	stMsg			VARCHAR2(250);
    	stWOWS		VARCHAR2(8);
    	nuWO			NUMBER;
    	nuWS			NUMBER;
    	nuROW_ID		NUMBER;
    	nuOldStatus		NUMBER;
    	dtWS02 DATE;
      nudebug			NUMBER    := 0;
    
    	/* CURSEUR */
    	CURSOR Cur_SEL_WS( pnucd_WS IN NUMBER, pnucd_WO IN NUMBER)
    	IS
    		SELECT * FROM WS WHERE CD_WOWS_STATUS < WS_CLOSED AND CD_WOWS_STATUS > WS_PREPARE AND CD_WS = pnucd_WS AND CD_WO = pnucd_WO;
       
              
    BEGIN
    	nuRet :=0;
        -- Ouverture du fichier en sortie
    
      IF stAction ='AfterFileOpening'
      THEN
    		/* juste apres ouverture des fichier et avant lecture du premier enregistrement */
    		UTL_FILE.PUTF( Imp_Param.hFileError, IMPORT_INFO_WS_TITLE, TO_CHAR(SYSDATE,'YYYYMMDD/HH24:MI:SS'));
    		UTL_FILE.NEW_LINE( Imp_Param.hFileError);
    		nuRet :=0;
      
          BEGIN  
        Rapport := UTL_FILE.FOPEN ('F:\HOTLINE-ACCUEIL\07-traitement CARL\Rapport', 'S04-Rapport_annulation-'||TO_CHAR(SYSDATE,'YYYYMMDD_HH24MI')||'.txt', 'w');
        UTL_FILE.FCLOSE(Rapport);    
        END;    
    
      ELSIF stAction ='AfterRecordControl'
      THEN
          		/* apres controle des champs de l'enregistrement
          		|| si refus de l'enregistrement par le controle nuRet = 1 sinon = 0
          		||
          		*/
          		nuWarning := 0;
              Enreg_Param.Rejected := FALSE;
    
    	      	BEGIN
    	      		/*On separe les code wo et ws contenus dans FIT*/
    	      		stWOWS := RTRIM(TO_CHAR (TablField(1)));
    	      		nuWO := TO_NUMBER(SUBSTR( stWOWS, 1 ,LENGTH( stWOWS) -2));
    	      		nuWS := TO_NUMBER(SUBSTR( stWOWS, LENGTH( nuWO) + 1  ,LENGTH( nuWO) + 3));
                
    	      		IF 	TRIM(TablField(3)) IS NOT NULL THEN
    	      			dtWS02 := TO_DATE(TablField(3),'DDMMYYHH24MI');
    	      		ELSE
    	      			dtWS02 :='';
    	      		END IF;
    
    	      		FOR CUR IN Cur_SEL_WS(nuWS, nuWO )
    	      		LOOP           
    	      			nuOldStatus := CUR.CD_WOWS_STATUS;
    	      			dtDTTM_IN_PROGRESS := NULL;
    	      			IF nuOldStatus IN ('5','6','7','8') AND TablField(5) = 4
    	      			THEN
    
    ------------------------- rapport : intervention annulée
                    IF CUR.DT_WS04 IS NOT NULL THEN
                    stRap := 'OT ' || TO_CHAR(CUR.CD_WO) || ' : intervention déplanifiée (ancienne date :' || CUR.DT_WS04 || ')\n' || chr(10) || chr(13) ;
                    Rapport := UTL_FILE.FOPEN ('F:\HOTLINE-ACCUEIL\07-traitement CARL\Rapport', 'S04-Rapport_annulation'||TO_CHAR(SYSDATE,'YYYYMMDD_HH24MI')||'.txt', 'a');
                    UTL_FILE.PUTF( Rapport , stRap);
                    UTL_FILE.FCLOSE(Rapport);
                    END IF;
                    nudebug:=nudebug+1;
                    
    		      			UPDATE WS SET
    	      					VAL_WS02 = TablField(6),
    		      			 	WHERE CD_WO = CUR.CD_WO AND CD_WS = CUR.CD_WS;
    
    	      			ELSE
                    nudebug:=nudebug+100;
    		      			IF TablField(5) = 5
    		      			THEN
    		      				dtDTTM_IN_PROGRESS := SYSDATE;
    		      			END IF;
    		      			
    		      				nuROW_ID := NULL;
    		      				CMST_WO_STATUS.Status_WO(CUR.CD_WO, nuOldStatus, nuROW_ID);          
    
    		      		END IF;
    	      		END LOOP;
    	      	EXCEPTION
    	      		WHEN OTHERS THEN
    	      			nuRet := SQLCODE;
    	      			stMsg := SQLERRM;
                  
    		END;
    
    	ELSIF stAction ='Close' THEN
          		/* appel avant destruction du fichier d'import
          		|| le fichier d'erreur et celui d'import sont deja fermes
          		|| si retourne nuRet<>0 le fichier d'import n'est pas supprime
          		*/
          		nuRet := 0;
              Rapport := UTL_FILE.FOPEN ('F:\CNT\HOTLINE-ACCUEIL\07-traitement CARL\Rapport Planning SPIE', 'DEBUG')||'.txt', 'w');
              UTL_FILE.PUTF( Rapport , nudebug);
              UTL_FILE.FCLOSE(Rapport);
              
       	END IF;
    EXCEPTION
    	WHEN OTHERS THEN
    	       	IF UTL_FILE.IS_OPEN(Imp_Param.hFileError)
    	       	THEN
    	          	UTL_FILE.PUTF(Imp_Param.hFileError, IMPORT_BIG_ERR, TO_CHAR (Enreg_Param.Line ));
    	          	UTL_FILE.NEW_LINE(Imp_Param.hFileError);
    	          	UTL_FILE.PUT(Imp_Param.hFileError,IMPORT_ERROR);
    	          	UTL_FILE.PUT(Imp_Param.hFileError,SQLCODE);
    	          	UTL_FILE.PUT(Imp_Param.hFileError,' - ' || SUBSTR(SQLERRM,1,150));
    	          	UTL_FILE.NEW_LINE(Imp_Param.hFileError);
    	 	  	Enreg_Param.Rejected := TRUE;
    	 	  	nuret := 1;
    	 	  	ROLLBACK;
    		END IF;
    		RAISE_APPLICATION_ERROR(-20001,'Erreur dans import_INFO_WS_ASCII'||TO_CHAR(SQLCODE));
    END;

  6. #6
    Expert confirmé Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Par défaut
    La variable nudebug a une portée qui s’étend a l’ensemble de votre procédure. Mais, je pense que vous avez un problème de logique du traitement. En fait la procédure est appelé plusieurs fois, avec de stAction différentes, mais la valeur de la variable nudegug est écrite seulement quand stAction = close. Dans ce cas la valeur de la variable nudebug est toujours 0.

  7. #7
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    72
    Détails du profil
    Informations personnelles :
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Mai 2010
    Messages : 72
    Par défaut
    Aie!
    Merci pour la réponse, je me doutais que quelque chose d'évident m'échappais .

    Pour placer le contexte, nous utilisons une application, sur laquelle nous n'avons accès qu'à quelques composants.
    Dont le package avec cette procédure.
    Il s'agit de traiter un fichier et d'en importer les lignes. N'ayant que ça, j'ai attaqué direct... Il faudrait donc que ma variable soit récupéré à chaque fois; puis écrite sur fermeture.
    Sauf que n'ayant pas accès aux autres traitements... faut que je fasse avec .

    A part écrire direct dans le fichier (création du fichier "w" dans la boucle 'AfterFileOpening', écriture de mon texte "a" dans le traitement 'AfterRecordControl'), ou la solution logique plus haut mais difficile dans mon cas, y aurait-il d'autres solutions.
    Là, ça me fais un fichier même si rien n'est écrit... pas top (1 traitement/10mn, ça fait mal!)

    Si quelqu'un a une solution miracle (sisi, ça arrive), un grand merci.

    PS : et merci mnitu pour m'avoir forcé à regarder l'évidence .

  8. #8
    Expert confirmé Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Par défaut
    Vous pouvez gérer votre variable en IN OUT en modifiant la signature de la procédure. Si vous ne pouvez pas modifier la signature de la procédure, pour stoker/récupérer la valeur nudebug, vous pouvez soit utiliser un package maison, soit utiliser dbms_application_info.set_client_info ou un contexte, etc.

  9. #9
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    72
    Détails du profil
    Informations personnelles :
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Mai 2010
    Messages : 72
    Par défaut
    La signature, malheureusement non.
    Mais le package maison... bonne idée, à défaut de pouvoir modifier au mieux la procédure existante, je vais rediriger vers mon propre traitement.

    Merci pour votre aide, je vais bosser la question!

    PS : Paf, je passe en résolu. Pas encore fonctionnel, mais j'ai des pistes pour me permettre d'avancer.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. probleme transmission de variable toute bete
    Par mereyj dans le forum Général JavaScript
    Réponses: 5
    Dernier message: 13/03/2006, 20h18
  2. [Sécurité] PHP 5 transmission de variables
    Par messier79 dans le forum Langage
    Réponses: 18
    Dernier message: 09/01/2006, 14h05
  3. Transmission de variable avec GET et header
    Par spirou dans le forum Langage
    Réponses: 10
    Dernier message: 03/01/2006, 19h04
  4. [FLASH MX] Transmission de variables entre 2 swf
    Par totoche dans le forum Flash
    Réponses: 3
    Dernier message: 12/10/2005, 15h54
  5. transmission de variables
    Par nicerico dans le forum ASP
    Réponses: 14
    Dernier message: 16/08/2004, 16h20

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo