2017-02-01 1 views
0

Je suis en train d'écrire une macro sas, où j'essaie de rejoindre l'une des deux colonnes, selon ce qui existe. Mais quand je donne quelque chose comme cela, il erreur sur, car il veut à la fois les colonnes existent:J'ai besoin de joindre une condition sur l'une des deux colonnes (selon ce qui existe)

%Macro Base_pop(ssc,input_table,POPN_TBL); 

PROC SQL; 
    CREATE TABLE test_&ssc. AS 
     SELECT B.ACCOUNT_ID 
     FROM ADL_EXT.&input_table.TB INNER JOIN 
      ADL_BSE.BRDM_POP_FLG_&POPN_TBL.B 
      ON B.ACCOUNT_ID = (CASE WHEN %sysfunc(exist(TB.ACCOUNT_ID)) then TB.ACCOUNT_ID 
            ELSE TB.FAC_ID                  
           END) 
     WHERE B.FLG = 'Y' 
     ORDER BY B.ACCOUNT_ID ; 

QUIT; 

%MEND; 

Les erreurs de code en disant TB.Account_id n'existe pas. J'ai aussi essayé la coalescence, ça n'a pas marché aussi.

Une seule des deux colonnes existerait sur les tables transmises à la macro. Donc, je dois rejoindre dynamiquement la colonne qui existe dans ma table actuelle.

Suggestions, s'il vous plaît!

+0

1) La fonction EXIST() teste l'existence d'un ensemble de données, et non d'une variable. (2) Depuis que vous avez créé une macro, vous pouvez utiliser la logique% IF pour générer de manière conditionnelle le code SAS que vous voulez exécuter. De cette façon, vous ne pouvez pas générer de références à des variables qui n'existent pas. Votre exemple n'a aucun code généré de manière conditionnelle. Je suppose que vous voulez remplacer l'instruction CASE par l'instruction% IF ..% THEN% ELSE. – Tom

+0

Vous ne pouvez pas avoir le programmeur qui appelle la macro dire à la macro quel nom de variable à utiliser? – Tom

+0

Merci pour votre réponse Tom! La macro est grande et utilise diverses colonnes qui pourraient exister pour plusieurs tables et pas pour d'autres. Même après que le conditionnel% si la logique est faux, pourquoi le compilateur recherche-t-il les noms de variables qui suivent une condition fausse. Ce n'est pas seulement cette colonne, j'ai plusieurs de ces colonnes, je ne veux pas continuer à ajouter des paramètres, nous n'avons pas de travail. – Rhea

Répondre

0

La description de votre problème indique que vous voulez tester l'existence de variables, mais vous n'avez inclus aucun code pour le faire. Une façon de faire ce test consiste à interroger les métadonnées SAS sur la table. Donc, ce code ci-dessous prendra le prénom, ACCOUNT_ID ou FAC_ID, qu'il trouve dans l'ensemble de données en entrée et l'utilisera. Si aucun n'est trouvé, il écrit un message d'erreur dans le journal SAS.

%macro base_pop(ssc,input_table,popn_tbl); 
%local out ina inb var ; 
%let out=test_&ssc ; 
%let ina=%upcase(adl_ext.&input_table); 
%let inb=%upcase(adl_bse.brdm_pop_flg_&popn_tbl); 

proc sql noprint ; 
    select name into :var 
    from dictionary.columns 
    where libname = "%scan(&ina,1,.)" 
     and memname="%scan(&ina,2,.)" 
     and upcase(name) in ('ACCOUNT_ID','FAC_ID') 
    ; 
%if (&sqlobs) %then %do; 
    create table &out as 
    select b.account_id 
    from &ina a inner join &inb b 
    on b.account_id = a.&var 
    where b.flg = 'y' 
    order by b.account_id 
    ; 
%end; 
%else %put ERROR: Could not find either ACCOUNT_ID or FAC_ID in &ina ; 

quit; 

%mend base_pop; 
+0

Merci Tom! Mais comme je l'ai mentionné, j'ai plusieurs vérifications de ce type dans le code, pour joindre de manière conditionnelle les colonnes qui existent. Je ne veux pas aller chercher et ensuite créer des variables de macro pour chacun d'eux, je préfère les passer en tant que variables macro alors. Besoin de rendre le code plus rapide et efficace. – Rhea