PROC SQL в макросе SAS для отображения всех переменных набора данных - оператор SELECT, вызывающий ошибку - PullRequest
0 голосов
/ 11 апреля 2019

Я пытался создать макрос для вывода списка всех переменных определенного набора данных. В моем макросе я использую PROC SQL. Код работает нормально за пределами %macro, но сообщение об ошибке говорит, что оператор SELECT недопустим, когда он используется в %MACRO

вот пример:

  proc sql noprint;
     select name into :vlist separated by ' '
     from dictionary.columns
     where memname = upcase("&dsn");
  quit;
  %put &vlist;

выше работает отлично;

но

%macro getvars(dsn);
%local vlist;
proc sql noprint;
    select name into :vlist separated by ' '
    from dictionary.columns
    where memname = upcase("&dsn");
quit;
&vlist;
%mend;

вышесказанное не работает, когда я пытался это сделать:

%let var_list = %getvars(dataset);

возвращает:

ОШИБКА 180-322: оператор недействителен или используется не по порядку.

подчеркивая оператор SELECT в PROC SQL

Ответы [ 3 ]

0 голосов
/ 11 апреля 2019

Макросы SAS не похожи на функции в большинстве языков программирования: они не возвращают значений, они фактически заменяются содержимым макроса.

Решение состоит в том, чтобы сделать вашу макропеременную глобальной, вне макроса. Тогда вам не нужно присваивать его новой макро-переменной с %let.

%global vlist;
%macro getvars(dsn);
    proc sql noprint;
        select name into :vlist separated by ' '
        from dictionary.columns
        where memname = upcase("&dsn");
    quit;
%mend;
%getvars(work.class)
%put &=vlist;

[EDIT]
а затем просто используйте список в вашем операторе keep

data OUT (keep= &vlist. VAR_B1);
    merge DATA_A (in=a) DATA_B (in=b) ;
run;
0 голосов
/ 11 апреля 2019

Похоже, что единственный жизнеспособный вариант для моего варианта использования взят из следующей статьи SAS, в разделе «ИСПОЛЬЗОВАНИЕ МАКРОПЕТИ»

https://support.sas.com/resources/papers/proceedings/proceedings/sugi30/028-30.pdf

Чтобы уточнить, мой вариант использования требует непосредственного вывода самого списка, а не макропеременной.

например.

data OUT (keep= %getvars(DATA_A) VAR_B1);
merge DATA_A (in=a)
      DATA_B (in=b)
      ;
run;

PROC SQL не будет работать для меня. Поэтому я думаю, что мне нужно перейти к SAS I/O функциям в Macro Loop.

Ниже из бумаги SAS:

%Macro GetVars(Dset) ;
  %Local VarList ;
  /* open dataset */
  %Let FID = %SysFunc(Open(&Dset)) ; 
  /* If accessable, process contents of dataset */
  %If &FID %Then %Do ;
  %Do I=1 %To %SysFunc(ATTRN(&FID,NVARS)) ;
  %Let VarList= &VarList %SysFunc(VarName(&FID,&I));
  %End ;
  /* close dataset when complete */
  %Let FID = %SysFunc(Close(&FID)) ;
  %End ;
  &VarList 
%Mend ;
0 голосов
/ 11 апреля 2019
%let var_list = %getvars(dataset);

разрешит до:

%let var_list = proc sql noprint;
    select name into :vlist separated by ' '
    from dictionary.columns
    where memname = upcase("dataset");
quit;

Таким образом, он будет хранить proc sql noprint в var_list, а затем потерпит неудачу, потому что вы используете proc sql за пределами proc sql.

...