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

Macro Discussion :

Erreur %goto et proc sql dans une macro


Sujet :

Macro

  1. #1
    Membre régulier

    Inscrit en
    Novembre 2007
    Messages
    121
    Détails du profil
    Informations forums :
    Inscription : Novembre 2007
    Messages : 121
    Points : 104
    Points
    104
    Par défaut Erreur %goto et proc sql dans une macro
    Bonjour, j'ai ce code :

    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
    %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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : 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
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    proc sql;
    create table matrix_state (id_matrix_state num(10), matrix_state_name char(20));
    quit;

  2. #2
    Membre émérite

    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Mars 2005
    Messages
    1 364
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Consultant en Business Intelligence
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 364
    Points : 2 329
    Points
    2 329
    Par défaut
    essayes de mettre un ';' après ton étiquette "%restart:;"
    Consultez les FAQs et les anciens postes avant de poser vos questions. Merci

  3. #3
    Membre régulier

    Inscrit en
    Novembre 2007
    Messages
    121
    Détails du profil
    Informations forums :
    Inscription : Novembre 2007
    Messages : 121
    Points : 104
    Points
    104
    Par défaut
    Ah oui, pardon. Je croyais l'avoir sélectionnée.

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

  4. #4
    Membre émérite

    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Mars 2005
    Messages
    1 364
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Consultant en Business Intelligence
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 364
    Points : 2 329
    Points
    2 329
    Par défaut
    Attention ton programme risque de boucler.
    Si il ya des problèmes avec la base Oracle
    Consultez les FAQs et les anciens postes avant de poser vos questions. Merci

  5. #5
    Membre régulier

    Inscrit en
    Novembre 2007
    Messages
    121
    Détails du profil
    Informations forums :
    Inscription : Novembre 2007
    Messages : 121
    Points : 104
    Points
    104
    Par défaut
    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à...

  6. #6
    Membre régulier

    Inscrit en
    Novembre 2007
    Messages
    121
    Détails du profil
    Informations forums :
    Inscription : Novembre 2007
    Messages : 121
    Points : 104
    Points
    104
    Par défaut
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    	%let return = %sysfunc(compress(&ident,%str(% )));
    	%put L identifiant return est :*&return*;
    	&return;
    %mend;
    par celles-ci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    %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...

  7. #7
    Membre émérite

    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Mars 2005
    Messages
    1 364
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Consultant en Business Intelligence
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 364
    Points : 2 329
    Points
    2 329
    Par défaut
    Quand je mets une virgule après l'étiquette %restart: le programme ne signal plus le poblème du select!!

    Cool si ça marche
    Consultez les FAQs et les anciens postes avant de poser vos questions. Merci

  8. #8
    Membre régulier

    Inscrit en
    Novembre 2007
    Messages
    121
    Détails du profil
    Informations forums :
    Inscription : Novembre 2007
    Messages : 121
    Points : 104
    Points
    104
    Par défaut
    Ah ?

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

    Ca donne donc ça ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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.

  9. #9
    Membre régulier

    Inscrit en
    Novembre 2007
    Messages
    121
    Détails du profil
    Informations forums :
    Inscription : Novembre 2007
    Messages : 121
    Points : 104
    Points
    104
    Par défaut
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : 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
    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
    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 :
    ✠✠

  10. #10
    Membre régulier

    Inscrit en
    Novembre 2007
    Messages
    121
    Détails du profil
    Informations forums :
    Inscription : Novembre 2007
    Messages : 121
    Points : 104
    Points
    104
    Par défaut
    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 : 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
    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);

  11. #11
    Membre régulier

    Inscrit en
    Novembre 2007
    Messages
    121
    Détails du profil
    Informations forums :
    Inscription : Novembre 2007
    Messages : 121
    Points : 104
    Points
    104
    Par défaut
    Le code au dessus vous permet de reproduire exactement le bug. Si vous savez comment contourner ce problème, je suis toute ouïe.

  12. #12
    Membre émérite

    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Mars 2005
    Messages
    1 364
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Consultant en Business Intelligence
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 364
    Points : 2 329
    Points
    2 329
    Par défaut
    1 Tu as des problème de nom de variables
    2 Je ne comprends pas prq tu fais ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : 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
     
    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);
    Consultez les FAQs et les anciens postes avant de poser vos questions. Merci

  13. #13
    Membre régulier

    Inscrit en
    Novembre 2007
    Messages
    121
    Détails du profil
    Informations forums :
    Inscription : Novembre 2007
    Messages : 121
    Points : 104
    Points
    104
    Par défaut
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    %let var=&column_tmp.__&j_;
    %let var = %str(%'&&&var%');
    Avec par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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 ?

  14. #14
    Membre régulier

    Inscrit en
    Novembre 2007
    Messages
    121
    Détails du profil
    Informations forums :
    Inscription : Novembre 2007
    Messages : 121
    Points : 104
    Points
    104
    Par défaut
    En fait, on peut illustrer le soucis le plus simplement avec le code suivant (à exécuter tel quel ):

    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
    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 : 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
    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 :
    SYMBOLGEN: Some characters in the above value which were subject to macro quoting have been unquoted for printing.

  15. #15
    Membre émérite

    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Mars 2005
    Messages
    1 364
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Consultant en Business Intelligence
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 364
    Points : 2 329
    Points
    2 329
    Par défaut
    Tous simplement tu rajoutes une double quote dans la proc SQL
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    Consultez les FAQs et les anciens postes avant de poser vos questions. Merci

  16. #16
    Membre régulier

    Inscrit en
    Novembre 2007
    Messages
    121
    Détails du profil
    Informations forums :
    Inscription : Novembre 2007
    Messages : 121
    Points : 104
    Points
    104
    Par défaut


    Eh bien...

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

    Merci infiniment !

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

Discussions similaires

  1. Requête SQL dans une macros Excel
    Par Lebijuu dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 23/05/2014, 13h58
  2. Paramétrer une proc sql dans un macro programme
    Par statisticien35 dans le forum Macro
    Réponses: 2
    Dernier message: 09/01/2013, 14h58
  3. Réponses: 2
    Dernier message: 21/01/2010, 17h02
  4. Erreur de lecture de données dans une requête SQL
    Par PtiteDéveloppeuse dans le forum Requêtes
    Réponses: 0
    Dernier message: 10/01/2008, 11h29
  5. Réponses: 3
    Dernier message: 28/08/2007, 15h21

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