Précédent   Forum des professionnels en informatique > Logiciels > Solutions d'entreprise > Business Intelligence > SAS > Macro
Macro Forum d'entraide sur le langage Macro de SAS
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 16/04/2008, 16h47   #1
Membre du Club
 
Inscription : novembre 2007
Messages : 120
Détails du profil
Informations forums :
Inscription : novembre 2007
Messages : 120
Points : 56
Points : 56
Par défaut Erreur %goto et proc sql dans une macro

Bonjour, j'ai ce code :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
%macro select_id_FK(TABLE, column_, var, column_ident);
	%let ident=;
	%restart: %put Retour à la case départ ;
	proc sql;
		SELECT &column_ident INTO :ident FROM LBMTST03.&TABLE. WHERE &column_=&var;
	quit;
	%put ident IS **&ident**;
	%IF %length(&ident)=0 %then %do;
		proc sql;
			connect TO oracle (USER='user' PASSWORD='pswrd' path=LBMTST03);
				SELECT NEXTVAL INTO :identifiant FROM connection TO oracle (SELECT no_id_&TABLE..NEXTVAL FROM dual);
				INSERT INTO lbmtst03.&TABLE (id_&TABLE., &column_) VALUES (&identifiant, &var);
			disconnect FROM oracle;
		quit;
		%put ident IS **&ident** IN IF loop;
		%put identifiant IS **&identifiant** IN IF loop;
		%goto restart;
	%end;
	%let RETURN = %sysfunc(compress(&ident,%str(% )));
	%put L identifiant RETURN est :*&RETURN*;
	&RETURN;
%mend;
En fait, ce que je veux faire, c'est aller chercher un identifiant ('column_FK' qui est une clé primaire) dans une table 'table_tmp' en regardant la valeur ('var') d'un champ précis ('column_tmp'). Même si ce champs (var) n'est pas codé comme étant une clé primaire, en pratique, c'en est une, il y a moins d'une dizaine d'entrée dans cette table. Donc ce qui est fait c'est récupérer la clé primaire correspondant à la valeur (var) ou bien rajouter dans la table une nouvelle valeur avec var et récupérer la clé primaire qui a été créée lors de la création (d'où l'intérêt du %goto).

Je l'appelle avec ceci :

Code :
1
2
3
4
5
6
7
OPTIONS MLOGIC MPRINT SYMBOLGEN;
%let table_tmp = matrix_state;
%let column_tmp = matrix_state_name;
%let var = 'Freshes';
%let column_FK = id_matrix_state;
%put &table_tmp, &column_tmp, &var, &column_FK;
%let test = %select_id_FK(&table_tmp, &column_tmp, &var, &column_FK);
Et voilà le log que j'ai :

Code :
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
13         %gaccessible;
14         %let test = %select_id_FK(&table_tmp, &column_tmp, &var, &column_FK);
Retour à la case départ
ERROR 180-322: Statement is not valid or it is used out of proper order.
NOTE: Line generated by the invoked macro "SELECT_ID_FK".
14          proc sql;   select &column_ident into :ident from LBMTST03.&table. where &column_=&var;  quit;
                        ______
                        180


ident is ****
NOTE: 1 row was inserted into LBMTST03.MATRIX_STATE.

NOTE: PROCEDURE SQL used (Total process time):
      real time           0.34 seconds
      cpu time            0.09 seconds
      

ident is **** in if loop
identifiant is **     128** in if loop
Retour à la case départ
NOTE: PROCEDURE SQL used (Total process time):
      real time           0.17 seconds
      cpu time            0.03 seconds
      

ident is **         87**
L identifiant return est :*87*

NOTE: Line generated by the macro variable "RETURN".
14           87
             __
             180
ERROR 180-322: Statement is not valid or it is used out of proper order.
15         
16         
17         %LET _CLIENTTASKLABEL=;
18         %LET _EGTASKLABEL=;
19         %LET _CLIENTPROJECTNAME=;
20         %LET _SASPROGRAMFILE=;

Il y a deux erreurs, et je ne comprends aucun des deux...

Une idée ?


edit : pour info la table matrix_state contient uniquement des deux champs :
'id_matrix_state' qui est un number(10)
'matrix_state_name' qui est un char(20)
Et le champ 'id_matrix_state' est une séquence (d'où le '.nextval from dual' dans la macro en tout cas, cette partie fonctionne bien, de ce côté là, pas de soucis)

Code :
1
2
3
4
 
proc sql;
CREATE TABLE matrix_state (id_matrix_state num(10), matrix_state_name char(20));
quit;
raf64flo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/04/2008, 16h55   #2
Membre Expert
 
Inscription : mars 2005
Messages : 1 028
Détails du profil
Informations forums :
Inscription : mars 2005
Messages : 1 028
Points : 1 278
Points : 1 278
Envoyer un message via Yahoo à bahraoui
essayes de mettre un ';' après ton étiquette "%restart:;"
bahraoui est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/04/2008, 16h59   #3
Membre du Club
 
Inscription : novembre 2007
Messages : 120
Détails du profil
Informations forums :
Inscription : novembre 2007
Messages : 120
Points : 56
Points : 56
Ah oui, pardon. Je croyais l'avoir sélectionnée.

Code :
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
13         %gaccessible;
MLOGIC(GACCESSIBLE):  Beginning execution.
MLOGIC(GACCESSIBLE):  %LOCAL  ACCESSIBLE
MLOGIC(GACCESSIBLE):  %LOCAL  GRAPHAVAIL
SYMBOLGEN:  Macro variable SYSVLONG resolves to 9.01.01M3P061705
MLOGIC(GACCESSIBLE):  %IF condition %SCAN(&SYSVLONG, 1, .) ne 8 is TRUE
MLOGIC(GACCESSIBLE):  %LET (variable name is GRAPHAVAIL)
SYMBOLGEN:  Macro variable GRAPHAVAIL resolves to 9.01 TS1M3
MLOGIC(GACCESSIBLE):  %IF condition (%sysfunc(index(&graphavail,TS)) > 0) is TRUE
MLOGIC(GACCESSIBLE):  %LET (variable name is ACCESSIBLE)
SYMBOLGEN:  Macro variable ACCESSIBLE resolves to ACCESSIBLE
MLOGIC(GACCESSIBLE):  %IF condition (&accessible^=) is TRUE
MPRINT(GACCESSIBLE):   GOPTIONS ACCESSIBLE;
MLOGIC(GACCESSIBLE):  Ending execution.
14         %let test = %select_id_FK(&table_tmp, &column_tmp, &var, &column_FK);
MLOGIC(SELECT_ID_FK):  Beginning execution.
SYMBOLGEN:  Macro variable TABLE_TMP resolves to matrix_state
SYMBOLGEN:  Macro variable COLUMN_TMP resolves to matrix_state_name
SYMBOLGEN:  Macro variable VAR resolves to 'Freshes'
SYMBOLGEN:  Macro variable COLUMN_FK resolves to id_matrix_state
MLOGIC(SELECT_ID_FK):  Parameter TABLE has value matrix_state
MLOGIC(SELECT_ID_FK):  Parameter COLUMN_ has value matrix_state_name
MLOGIC(SELECT_ID_FK):  Parameter VAR has value 'Freshes'
MLOGIC(SELECT_ID_FK):  Parameter COLUMN_IDENT has value id_matrix_state
MLOGIC(SELECT_ID_FK):  %LET (variable name is IDENT)
MLOGIC(SELECT_ID_FK):  %PUT Retour à la case départ
Retour à la case départ
SYMBOLGEN:  Macro variable COLUMN_IDENT resolves to id_matrix_state
ERROR 180-322: Statement is not valid or it is used out of proper order.
NOTE: Line generated by the invoked macro "SELECT_ID_FK".
14          proc sql;   select &column_ident into :ident from LBMTST03.&table. where &column_=&var;  quit;
                        ______
                        180

SYMBOLGEN:  Macro variable TABLE resolves to matrix_state
SYMBOLGEN:  Macro variable COLUMN_ resolves to matrix_state_name
SYMBOLGEN:  Macro variable VAR resolves to 'Freshes'
MPRINT(SELECT_ID_FK):   select id_matrix_state into :ident from LBMTST03.matrix_state where matrix_state_name='Freshes';

2                                                          The SAS System                            16:32 Wednesday, April 16, 2008

MPRINT(SELECT_ID_FK):   quit;
MLOGIC(SELECT_ID_FK):  %PUT ident is **&ident**
SYMBOLGEN:  Macro variable IDENT resolves to 
ident is ****
SYMBOLGEN:  Macro variable IDENT resolves to 
MLOGIC(SELECT_ID_FK):  %IF condition %length(&ident)=0 is TRUE
MPRINT(SELECT_ID_FK):   proc sql;
MPRINT(SELECT_ID_FK):   connect to oracle (USER='tempo_test' PASSWORD='tempo_test' path=LBMTST03);
SYMBOLGEN:  Macro variable TABLE resolves to matrix_state
MPRINT(SELECT_ID_FK):   select nextval into :identifiant from connection to oracle (select no_id_matrix_state.nextval from dual);
SYMBOLGEN:  Macro variable TABLE resolves to matrix_state
SYMBOLGEN:  Macro variable TABLE resolves to matrix_state
SYMBOLGEN:  Macro variable COLUMN_ resolves to matrix_state_name
SYMBOLGEN:  Macro variable IDENTIFIANT resolves to      131
SYMBOLGEN:  Macro variable VAR resolves to 'Freshes'
MPRINT(SELECT_ID_FK):   insert into lbmtst03.matrix_state (id_matrix_state, matrix_state_name) values ( 131, 'Freshes');
NOTE: 1 row was inserted into LBMTST03.MATRIX_STATE.

MPRINT(SELECT_ID_FK):   disconnect from oracle;
MPRINT(SELECT_ID_FK):   quit;
NOTE: PROCEDURE SQL used (Total process time):
      real time           0.26 seconds
      cpu time            0.09 seconds
      

MLOGIC(SELECT_ID_FK):  %PUT ident is **&ident** in if loop
SYMBOLGEN:  Macro variable IDENT resolves to 
ident is **** in if loop
MLOGIC(SELECT_ID_FK):  %PUT identifiant is **&identifiant** in if loop
SYMBOLGEN:  Macro variable IDENTIFIANT resolves to      131
identifiant is **     131** in if loop
MLOGIC(SELECT_ID_FK):  %GOTO RESTART (label resolves to RESTART).
MLOGIC(SELECT_ID_FK):  %PUT Retour à la case départ
Retour à la case départ
MPRINT(SELECT_ID_FK):   proc sql;
SYMBOLGEN:  Macro variable COLUMN_IDENT resolves to id_matrix_state
SYMBOLGEN:  Macro variable TABLE resolves to matrix_state
SYMBOLGEN:  Macro variable COLUMN_ resolves to matrix_state_name
SYMBOLGEN:  Macro variable VAR resolves to 'Freshes'
MPRINT(SELECT_ID_FK):   select id_matrix_state into :ident from LBMTST03.matrix_state where matrix_state_name='Freshes';
MPRINT(SELECT_ID_FK):   quit;
NOTE: PROCEDURE SQL used (Total process time):
      real time           0.06 seconds
      cpu time            0.03 seconds
      

MLOGIC(SELECT_ID_FK):  %PUT ident is **&ident**
SYMBOLGEN:  Macro variable IDENT resolves to          87
ident is **         87**
SYMBOLGEN:  Macro variable IDENT resolves to          87
MLOGIC(SELECT_ID_FK):  %IF condition %length(&ident)=0 is FALSE
MLOGIC(SELECT_ID_FK):  %LET (variable name is RETURN)
SYMBOLGEN:  Macro variable IDENT resolves to          87
MLOGIC(SELECT_ID_FK):  %PUT L identifiant return est :*&return*
SYMBOLGEN:  Macro variable RETURN resolves to 87
L identifiant return est :*87*
SYMBOLGEN:  Macro variable RETURN resolves to 87
NOTE: Line generated by the macro variable "RETURN".
3                                                          The SAS System                            16:32 Wednesday, April 16, 2008

14           87
             __
             180
MPRINT(SELECT_ID_FK):   87;

ERROR 180-322: Statement is not valid or it is used out of proper order.

MLOGIC(SELECT_ID_FK):  Ending execution.
15         
16
raf64flo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/04/2008, 17h17   #4
Membre Expert
 
Inscription : mars 2005
Messages : 1 028
Détails du profil
Informations forums :
Inscription : mars 2005
Messages : 1 028
Points : 1 278
Points : 1 278
Envoyer un message via Yahoo à bahraoui
Attention ton programme risque de boucler.
Si il ya des problèmes avec la base Oracle
bahraoui est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/04/2008, 18h42   #5
Membre du Club
 
Inscription : novembre 2007
Messages : 120
Détails du profil
Informations forums :
Inscription : novembre 2007
Messages : 120
Points : 56
Points : 56
Comment ça il risque de boucler si il y a un problème avec la base ?

Tu parles du %goto restart qui ramène toujours au début si il ne retrouve pas l'identifiant qu'il a inséré ?

Je ne vois pas comment ce serait possible puisque la commande d'insertion semble correcte.

Ce qui ma gêne, c'est que sur certains tests tout à l'heure, au lieu de renvoyer l'identifiant dans return, ce qu'il renvoyait c'était texto :
"proc sql"...

Je n'ai pas compris pourquoi, pourtant la syntaxe me paraissait correcte avec le %label et le %goto.

Une suggestion ?

Je suis bien largué là...
raf64flo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/04/2008, 09h46   #6
Membre du Club
 
Inscription : novembre 2007
Messages : 120
Détails du profil
Informations forums :
Inscription : novembre 2007
Messages : 120
Points : 56
Points : 56
Bonjour !

Bon, après quelques prises de tête, j'ai abandonné l'idée de comprendre ce qui ne marchait pas hier.

En tout cas pour une partie.

En modifiant les 4 dernières lignes :
Code :
1
2
3
4
	%let RETURN = %sysfunc(compress(&ident,%str(% )));
	%put L identifiant RETURN est :*&RETURN*;
	&RETURN;
%mend;
par celles-ci :
Code :
1
2
3
4
	%global RETURN;
	%let RETURN = %sysfunc(compress(&ident,%str(% )));
	%put L identifiant RETURN est :*&RETURN*;
%mend;
Je n'ai plus d'erreur à l'exécution et celle-ci se fait correctement.

Je ne sais pas pourquoi il n'aimait pas mon &return assigné à une variable via un %let, mais le fait est qu'en passant par une variable globale que je supprime après l'avoir assignée à une autre variable locale après la macro, je contourne le problème. Pourtant j'ai déjà utilisé cette astuce à plusieurs reprises sans soucis... Barhaoui, si tu rencontres un truc similaire et que tu comprends ce qui ne va pas, n'hésite pas à préciser pourquoi.

Concernant l'erreur sur le 'select' par contre, j'ai pas compris...

Je me demande si ce n'était pas la rémanence de l'exécution d'une autre commande qui tournait toujours sur le serveur SAS... Quoique j'ai eu à nouveau ce soucis une seule fois ce matin, quand j'essayais d'exécuter la macro avec cette commande (commande que j'ai lancé à plusieurs reprises sans voir cette erreur spécifique) :
Code :
%let test = %select_id_FK(&table_tmp, &column_tmp, &var, &column_FK);
Le problème a disparu juste après lorsque j'ai réinitialisé les variables mises en paramètre...

Bizarrerie, quand tu nous tiens...
raf64flo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/04/2008, 10h21   #7
Membre Expert
 
Inscription : mars 2005
Messages : 1 028
Détails du profil
Informations forums :
Inscription : mars 2005
Messages : 1 028
Points : 1 278
Points : 1 278
Envoyer un message via Yahoo à bahraoui
Quand je mets une virgule après l'étiquette %restart: le programme ne signal plus le poblème du select!!

Cool si ça marche
bahraoui est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/04/2008, 10h43   #8
Membre du Club
 
Inscription : novembre 2007
Messages : 120
Détails du profil
Informations forums :
Inscription : novembre 2007
Messages : 120
Points : 56
Points : 56
Ah ?

Il n'aime donc pas que je mette la commande %put après le label ?

Ca donne donc ça ?
Code :
1
2
%restart: ;
%put Retour à la case départ;
Admettons. Je n'ai pas beaucoup utilisé les %goto, je n'en suis pas très expérimenté...

Merci.
raf64flo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/04/2008, 11h30   #9
Membre du Club
 
Inscription : novembre 2007
Messages : 120
Détails du profil
Informations forums :
Inscription : novembre 2007
Messages : 120
Points : 56
Points : 56
Retour ici...

Toujours avec la même macro, lorsque je l'appelle à partir d'une autre macro, j'ai une erreur, alors que si je l'exécute seule, pas de soucis.

Voici les commandes d'appel :
Code :
1
2
3
4
%let var=&column_tmp.__&j_;
%let var = %str(%'&&&var%');
%put TABLE:**&table_tmp**, Colonne_à_remplir-ou-à_vérifier:**&column_tmp**, contenu_colonne:**&var**, colonne_identifiant:**&column_FK**;
%select_id_FK(&table_tmp, &column_tmp, &var, &column_FK);
Et voici le log correspondant :
Code :
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
MLOGIC(TUTU2):  %LET (variable name is VAR)
SYMBOLGEN:  Macro variable COLUMN_TMP resolves to matrix_type_name
SYMBOLGEN:  Macro variable J_ resolves to 1
MLOGIC(TUTU2):  %LET (variable name is VAR)
6                                                          The SAS System                             10:45 Thursday, April 17, 2008

SYMBOLGEN:  && resolves to &.
SYMBOLGEN:  Macro variable VAR resolves to matrix_type_name__1
SYMBOLGEN:  Macro variable MATRIX_TYPE_NAME__1 resolves to Plats cuisinés
MLOGIC(TUTU2):  %PUT table:**&table_tmp**, Colonne_à_remplir-ou-à_vérifier:**&column_tmp**, contenu_colonne:**&var**, 
      colonne_identifiant:**&column_FK**
SYMBOLGEN:  Macro variable TABLE_TMP resolves to matrix_type
SYMBOLGEN:  Macro variable COLUMN_TMP resolves to matrix_type_name
SYMBOLGEN:  Macro variable VAR resolves to 'Plats cuisinés'
SYMBOLGEN:  Some characters in the above value which were subject to macro quoting have been unquoted for printing.
SYMBOLGEN:  Macro variable COLUMN_FK resolves to id_matrix_type
table:**matrix_type**, Colonne_à_remplir-ou-à_vérifier:**matrix_type_name**, contenu_colonne:**'Plats cuisinés'**, 
colonne_identifiant:**id_matrix_type**
MLOGIC(SELECT_ID_FK):  Beginning execution.
SYMBOLGEN:  Macro variable TABLE_TMP resolves to matrix_type
SYMBOLGEN:  Macro variable COLUMN_TMP resolves to matrix_type_name
SYMBOLGEN:  Macro variable VAR resolves to 'Plats cuisinés'
SYMBOLGEN:  Some characters in the above value which were subject to macro quoting have been unquoted for printing.
SYMBOLGEN:  Macro variable COLUMN_FK resolves to id_matrix_type
MLOGIC(SELECT_ID_FK):  Parameter TABLE has value matrix_type
MLOGIC(SELECT_ID_FK):  Parameter COLUMN_ has value matrix_type_name
MLOGIC(SELECT_ID_FK):  Parameter VAR has value CARRE CARRE  Plats cuisinés CARRE CARRE 
MLOGIC(SELECT_ID_FK):  Parameter COLUMN_IDENT has value id_matrix_type
MLOGIC(SELECT_ID_FK):  %LET (variable name is IDENT)
MLOGIC(SELECT_ID_FK):  %PUT Retour à la case départ
Retour à la case départ
MPRINT(SELECT_ID_FK):   proc sql;
SYMBOLGEN:  Macro variable COLUMN_IDENT resolves to id_matrix_type
SYMBOLGEN:  Macro variable TABLE resolves to matrix_type
SYMBOLGEN:  Macro variable COLUMN_ resolves to matrix_type_name
SYMBOLGEN:  Macro variable VAR resolves to 'Plats cuisinés'
SYMBOLGEN:  Some characters in the above value which were subject to macro quoting have been unquoted for printing.
NOTE: Line generated by the macro variable "VAR".
14         'Plats cuisinés'
           _
           22
             _____
             202
MPRINT(SELECT_ID_FK):   select id_matrix_type into :ident from LBMTST03.matrix_type where matrix_type_name='Plats cuisinés';
ERROR 22-322: Syntax error, expecting one of the following: a name, a quoted string, a numeric constant, a datetime constant, 
              a missing value, (, *, +, -, ALL, ANY, BTRIM, CALCULATED, CASE, INPUT, LOWER, PUT, SELECT, SOME, SUBSTRING, 
              TRANSLATE, UPPER, USER.  

ERROR 202-322: The option or parameter is not recognized and will be ignored.

NOTE: PROC SQL set option NOEXEC and will continue to check the syntax of statements.
MPRINT(SELECT_ID_FK):   quit;
NOTE: The SAS System stopped processing this step because of errors.
NOTE: PROCEDURE SQL used (Total process time):
      real time           0.01 seconds
      cpu time            0.00 seconds
      
MLOGIC(SELECT_ID_FK):  %PUT ident is **&ident**
SYMBOLGEN:  Macro variable IDENT resolves to 
ident is ****
SYMBOLGEN:  Macro variable IDENT resolves to 
MLOGIC(SELECT_ID_FK):  %IF condition %length(&ident)=0 is TRUE
Le soucis doit venir de la variable var je pense car dansl e log, il n'affiche pas correctement les quote. C'est la zone que j'ai surlignée en mauve.

Notez qu'il manque ici (par rapport au log dans SEG) de part et d'autres de
Citation:
Plats cuisinés
deux carrés qui corresondent à des symboles non reconnus par SAS semble-t-il. Ils ne sont pas affichés ici, mais je les signale avec :
CARRE CARRE
Un peu comme lorsque dans le bloc note de windows on essaie de coller ces caractères :
✠✠
raf64flo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/04/2008, 11h52   #10
Membre du Club
 
Inscription : novembre 2007
Messages : 120
Détails du profil
Informations forums :
Inscription : novembre 2007
Messages : 120
Points : 56
Points : 56
Pour vous : (ça vous évitera de chercher quoi rentrer pour relancer le code, pensez à compiler la macro avant ) (à quelques erreurs prêt pour vous je pense )
Code :
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
OPTIONS MLOGIC MPRINT SYMBOLGEN;
 
proc sql;
CREATE TABLE matrix_state (id_matrix_state num(10), matrix_state_name char(20));
quit;
 
 
%macro select_id_FK(TABLE, column_, var, column_ident);/* Sélectionne l'identifiant d'une Foreign Key et rajoute cette FK à la table si elle n'existe pas en renvoyant l'ID*/
	%let ident=;
	%restart: %put Retour à la case départ ;
	proc sql;
		SELECT &column_ident INTO :ident FROM work.&TABLE. WHERE &column_=&var;
	quit;
	%put ident IS **&ident**;
	%IF %length(&ident)=0 %then %do;
		proc sql;
				SELECT NEXTVAL INTO :identifiant FROM connection TO oracle (SELECT no_id_&TABLE..NEXTVAL FROM dual);
				INSERT INTO work.&TABLE (id_&TABLE., &column_) VALUES (&identifiant, &var);
		quit;
		%put ident IS **&ident** IN IF loop;
		%put identifiant IS **&identifiant** IN IF loop;
		%goto restart;
	%end;
	%global RETURN;
	%let RETURN = %sysfunc(compress(&ident,%str(% )));
	%put L identifiant RETURN est :*&RETURN*;
%mend;
 
 
%let table_tmp = matrix_state;
%let column_tmp = matrix_type_name;
%let matrix_type_name__1 = %sysfunc(compress('Plats cuisinés',%str(%')));
%let var = matrix_type_name__1;
%let column_fk = id_matrix_type;
%let var = %str(%'&&&var%');
%put table:**&table_tmp**, Colonne_à_remplir-ou-à_vérifier:**&column_tmp**, contenu_colonne:**&var**, colonne_identifiant:**&column_FK**;
%select_id_FK(&table_tmp, &column_tmp, &var, &column_FK);
raf64flo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/04/2008, 13h39   #11
Membre du Club
 
Inscription : novembre 2007
Messages : 120
Détails du profil
Informations forums :
Inscription : novembre 2007
Messages : 120
Points : 56
Points : 56
Le code au dessus vous permet de reproduire exactement le bug. Si vous savez comment contourner ce problème, je suis toute ouïe.
raf64flo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/04/2008, 14h17   #12
Membre Expert
 
Inscription : mars 2005
Messages : 1 028
Détails du profil
Informations forums :
Inscription : mars 2005
Messages : 1 028
Points : 1 278
Points : 1 278
Envoyer un message via Yahoo à bahraoui
1 Tu as des problème de nom de variables
2 Je ne comprends pas prq tu fais ça :

Code :
1
2
3
4
5
6
7
8
9
 
%let matrix_type_name__1 = %sysfunc(compress('Plats cuisinés',%str(%')));
/*supprimer les '*/
%put &matrix_type_name__1;
%let var = matrix_type_name__1;
%put &var;
%let var = %str(%'&&&var%');
/*ajouter les '*/
%put &var;
Ce code marche mais avec les modifs des noms de variables et la définitions de la macro var:
Code :
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
 
OPTIONS MLOGIC MPRINT SYMBOLGEN;
 
proc sql;
CREATE TABLE matrix_state (id_matrix_state num(10), matrix_state_name char(20));
quit;
 
 
%macro select_id_FK(TABLE, column_, var, column_ident);/* Sélectionne l'identifiant d'une Foreign Key et rajoute cette FK à la table si elle n'existe pas en renvoyant l'ID*/
	%let ident=;
	%restart: %put Retour à la case départ ;
	proc sql;
		SELECT &column_ident INTO :ident FROM work.&TABLE. WHERE &column_=&var;
	quit;
	%put ident IS **&ident**;
	%IF %length(&ident)=0 %then %do;
		proc sql;
				SELECT NEXTVAL INTO :identifiant FROM connection TO oracle (SELECT no_id_&TABLE..NEXTVAL FROM dual);
				INSERT INTO work.&TABLE (id_&TABLE., &column_) VALUES (&identifiant, &var);
		quit;
		%put ident IS **&ident** IN IF loop;
		%put identifiant IS **&identifiant** IN IF loop;
		%goto restart;
	%end;
	%global RETURN;
	%let RETURN = %sysfunc(compress(&ident,%str(% )));
	%put L identifiant RETURN est :*&RETURN*;
%mend;
 
 
%let table_tmp = matrix_state;
%let column_tmp = matrix_state_name;
%let matrix_type_name__1 = %sysfunc(compress('Plats cuisinés',%str(%')));
%let var = matrix_type_name__1;
%let column_fk = id_matrix_state;
%let var = %str(%'&&&var%');
%let var='Plats cuisinés';
%put table:**&table_tmp**, Colonne_à_remplir-ou-à_vérifier:**&column_tmp**, contenu_colonne:**&var**, colonne_identifiant:**&column_FK**;
%select_id_FK(&table_tmp, &column_tmp, &var, &column_FK);
bahraoui est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/04/2008, 14h31   #13
Membre du Club
 
Inscription : novembre 2007
Messages : 120
Détails du profil
Informations forums :
Inscription : novembre 2007
Messages : 120
Points : 56
Points : 56
Le code que j'ai mis, notamment la définition de var et matrix_state_name__1, c'est pour que vous puissiez compiler le code, je l'ai modifié car je n'ai pas exactement la même chose dans ma suite de macro (je vais pas filer tout le code ici, c'est pas utile).

Le soucis que j'ai pour définir var, c'est qu'il reçoit le contenu d'une autre variable et que celui-ci n'est pas entre quote.

Exemple :

Code :
1
2
%let var=&column_tmp.__&j_;
%let var = %str(%'&&&var%');
Avec par exemple :
Code :
1
2
3
4
5
6
7
8
%PUT Variable est : ***&column_tmp.__&j_*** ;
Variable est : ***matrix_state_name__1***
 
%PUT Contenu de variable est : ***&&&column_tmp.__&j_*** ;
Contenu de variable est : ***Plats cuisinés***
 
%PUT Contenu de variable est : ***&matrix_state_name__1*** ; /* même chose que juste au dessus*/
Contenu de variable est : ***Plats cuisinés***
Ensuite, je veux mettre ce contenu entre quote, d'où le %str(%') que je mets dans la deuxième définition de var.

C'est là que je pense m'y prendre mal. La solution du problème je pense réside là : comment rajouter des quote au contenu de matrix_state_name__1 ?
raf64flo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/04/2008, 14h57   #14
Membre du Club
 
Inscription : novembre 2007
Messages : 120
Détails du profil
Informations forums :
Inscription : novembre 2007
Messages : 120
Points : 56
Points : 56
En fait, on peut illustrer le soucis le plus simplement avec le code suivant (à exécuter tel quel ):

Code :
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
OPTIONS MLOGIC MPRINT SYMBOLGEN;
 
%let matrix_state_name__1 = plats cuisines;
%let column_tmp = matrix_state_name;
%let j_ = 1;
%let var=&column_tmp.__&j_;
%put var IS : **&var**;
%put contenu de var : **&&&var**;
%let var1 = %str(%'&&&var%');
%put Contenu de var1 : **&var1**;
 
 
proc sql;
CREATE TABLE matrix_state (id_matrix_state num(10), matrix_state_name char(20));
quit;
 
/* cette macro ne marche pas bien puisque les quote ne sont pas bien transmis à l'exécution (cf log), pourtant le code est correct*/
%macro insert1;
proc sql;
	INSERT INTO work.matrix_state (id_matrix_state, &column_tmp) VALUES (5, &var1);
quit;
%mend;
 
%insert1;
 
/* L'insertion suivante fonctionne parfaitement quand la donnée est envoyée en dur dans la requête sql*/
proc sql;
	INSERT INTO work.matrix_state (id_matrix_state, &column_tmp) VALUES (6, 'plat non cuisine');
quit;

Log :
Code :
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
13         %gaccessible;
MLOGIC(GACCESSIBLE):  Beginning execution.
MLOGIC(GACCESSIBLE):  %LOCAL  ACCESSIBLE
MLOGIC(GACCESSIBLE):  %LOCAL  GRAPHAVAIL
SYMBOLGEN:  Macro variable SYSVLONG resolves to 9.01.01M3P061705
MLOGIC(GACCESSIBLE):  %IF condition %SCAN(&SYSVLONG, 1, .) ne 8 is TRUE
MLOGIC(GACCESSIBLE):  %LET (variable name is GRAPHAVAIL)
SYMBOLGEN:  Macro variable GRAPHAVAIL resolves to 9.01 TS1M3
MLOGIC(GACCESSIBLE):  %IF condition (%sysfunc(index(&graphavail,TS)) > 0) is TRUE
MLOGIC(GACCESSIBLE):  %LET (variable name is ACCESSIBLE)
SYMBOLGEN:  Macro variable ACCESSIBLE resolves to ACCESSIBLE
MLOGIC(GACCESSIBLE):  %IF condition (&accessible^=) is TRUE
MPRINT(GACCESSIBLE):   GOPTIONS ACCESSIBLE;
MLOGIC(GACCESSIBLE):  Ending execution.
14         OPTIONS MLOGIC MPRINT SYMBOLGEN;
15         
16         %let matrix_state_name__1 = plats cuisines;
17         %let column_tmp = matrix_state_name;
18         %let j_ = 1;
SYMBOLGEN:  Macro variable COLUMN_TMP resolves to matrix_state_name
SYMBOLGEN:  Macro variable J_ resolves to 1
19         %let var=&column_tmp.__&j_;
SYMBOLGEN:  Macro variable VAR resolves to matrix_state_name__1
20         %put var is : **&var**;
var is : **matrix_state_name__1**
SYMBOLGEN:  && resolves to &.
SYMBOLGEN:  Macro variable VAR resolves to matrix_state_name__1
SYMBOLGEN:  Macro variable MATRIX_STATE_NAME__1 resolves to plats cuisines
21         %put contenu de var : **&&&var**;
contenu de var : **plats cuisines**
SYMBOLGEN:  && resolves to &.
SYMBOLGEN:  Macro variable VAR resolves to matrix_state_name__1
SYMBOLGEN:  Macro variable MATRIX_STATE_NAME__1 resolves to plats cuisines
22         %let var1 = %str(%'&&&var%');
SYMBOLGEN:  Macro variable VAR1 resolves to 'plats cuisines'
SYMBOLGEN:  Some characters in the above value which were subject to macro quoting have been unquoted for printing.
23         %put Contenu de var1 : **&var1**;
Contenu de var1 : **'plats cuisines'**
24         
2                                                          The SAS System                             14:36 Thursday, April 17, 2008

25         
26         proc sql;
27         create table matrix_state (id_matrix_state num(10), matrix_state_name char(20));
NOTE: Table WORK.MATRIX_STATE created, with 0 rows and 2 columns.
28         quit;
NOTE: PROCEDURE SQL used (Total process time):
      real time           0.29 seconds
      cpu time            0.01 seconds
      

29         
30         /* cette macro ne marche pas bien puisque les quote ne sont pas bien transmis à l'exécution (cf log), pourtant le code
30       ! est correct*/
31         %macro insert1;
32         proc sql;
33         	insert into work.matrix_state (id_matrix_state, &column_tmp) values (5, &var1);
34         quit;
35         %mend;
36         
37         %insert1;
MLOGIC(INSERT1):  Beginning execution.
MPRINT(INSERT1):   proc sql;
SYMBOLGEN:  Macro variable COLUMN_TMP resolves to matrix_state_name
SYMBOLGEN:  Macro variable VAR1 resolves to 'plats cuisines'
SYMBOLGEN:  Some characters in the above value which were subject to macro quoting have been unquoted for printing.
NOTE: Line generated by the macro variable "VAR1".
37          'plats cuisines'
            _
            22
              _____
              202
MPRINT(INSERT1):   insert into work.matrix_state (id_matrix_state, matrix_state_name) values (5, 'plats cuisines');
ERROR 22-322: Syntax error, expecting one of the following: a quoted string, a numeric constant, a datetime constant, 
              a missing value, ), +, ',', -, MISSING, NULL, USER.  

ERROR 202-322: The option or parameter is not recognized and will be ignored.

NOTE: PROC SQL set option NOEXEC and will continue to check the syntax of statements.
MPRINT(INSERT1):   quit;
NOTE: The SAS System stopped processing this step because of errors.
NOTE: PROCEDURE SQL used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds
      
MLOGIC(INSERT1):  Ending execution.
38         
39         /* L'insertion suivante fonctionne parfaitement quand la donnée est envoyée en dur dans la requête sql*/


40         proc sql;
41         	insert into work.matrix_state
41       ! (id_matrix_state, &column_tmp) values (6, 'plat non cuisine');
SYMBOLGEN:  Macro variable COLUMN_TMP resolves to matrix_state_name
NOTE: 1 row was inserted into WORK.MATRIX_STATE.

42         quit;
NOTE: PROCEDURE SQL used (Total process time):
      real time           0.00 seconds
3                                                          The SAS System                             14:36 Thursday, April 17, 2008

      cpu time            0.00 seconds
      

43         
44         
45         %LET _CLIENTTASKLABEL=;
46         %LET _EGTASKLABEL=;
47         %LET _CLIENTPROJECTNAME=;
48         %LET _SASPROGRAMFILE=;
49         
50         ;*';*";*/;quit;run;
51         ODS _ALL_ CLOSE;
52         
53         
54         QUIT; RUN;
55
Maintenant il faut voir si quelqu'un connaît une façon correcte de rajouter des quote au contenu d'une variable sans avoir ce message :
Citation:
SYMBOLGEN: Some characters in the above value which were subject to macro quoting have been unquoted for printing.
raf64flo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/04/2008, 16h52   #15
Membre Expert
 
Inscription : mars 2005
Messages : 1 028
Détails du profil
Informations forums :
Inscription : mars 2005
Messages : 1 028
Points : 1 278
Points : 1 278
Envoyer un message via Yahoo à bahraoui
Tous simplement tu rajoutes une double quote dans la proc SQL
Code :
1
2
3
4
 
	proc sql;
		SELECT &column_ident INTO :ident FROM work.&TABLE. WHERE &column_="&var";
	quit;
et tu n'est plus obligé d'ajouter des quote à ta macro variable
bahraoui est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/04/2008, 22h40   #16
Membre du Club
 
Inscription : novembre 2007
Messages : 120
Détails du profil
Informations forums :
Inscription : novembre 2007
Messages : 120
Points : 56
Points : 56


Eh bien...

Je devais être fatigué là... A trop se pencher sur le problème, on perd de vue la solution.

Merci infiniment !
raf64flo est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 15h41.


 
 
 
 
Partenaires

Hébergement Web