Reputation: 3682
How to use macros in SQL? (for every thing, that was selected)
I mean something like this:
&VarTable
is a table, which have two variables: (for example) Lib
and Table
Each observation in &VarTable
is the name of table: Lib.Table
I want to do things for every table:
1) exist?
2) sort it
and last condition:
each table, if it exist, have a variable &VarField
.
%macro mSortedTable(vLib,vTab,vVar);
%if %sysfunc(exist(&vLib..&vTab)) %then %do;
proc sort data = &vLib..&vTab;
by &vVar;
run;
&vLib..&vTab
%end;
%else %do; "" %end;
%mend mSortedTable;
proc sql noprint;
select %mSortedTable(vLib=Lib,vTab=Table,vVar=&VarField)
into: AccumVar separated by " "
from &VarTable;
quit;
how to do this with sql and macros?
Upvotes: 1
Views: 11017
Reputation: 28391
Call execute is a good solution, however if the data step code being "executed" is complicated (which it is not in this example), I find it hard to debug.
Another method is to put all the variables into macro variables and then loop through them in a macro do-loop;
(building on @cmjohns data)
/* create fake data */
data testdat;
length lib $8 table $32;
input lib $ table $;
datalines;
work test1
work test2
work test3
work doesnotexist
;
run;
/* create 3 data sets */
data work.test1 work.test2 work.test3;
input var1 var2 var3;
datalines;
1 34 8
2 54 5
12 5 6
;
run;
/* end create data */
%let VarTable=work.testdat;
%let VarField=var2 var3;
proc sql noprint;
select count(lib)
into :cnt
from &vartable;
%Let cnt=&cnt;
select strip(lib), strip(table)
into :lib1 - :lib&cnt, :table1 - :table&cnt
from &vartable;
quit;
%Macro test;
%Do i = 1 %to &cnt;
%Let lib=&&lib&i;
%Let table=&&table&i;
%Let dsn=&lib..&table;
%if %sysfunc(exist(&dsn)) %then %do;
Proc sort data=&dsn;
by &varfield;
run;
%end;
%else %do;
%put WARNING: The data set does not exist: &dsn;
%end;
%end;
%Mend;
%test
Upvotes: 1
Reputation: 4475
Do you have to use sql and macros? A simple data step and call execute
would do what you need here.
Below is an example that takes a data set that has a list of tables to process, checks to see if the table exists and if it does, sorts it by &VarField. This could be easily extended to sort each table by a custom set of variables if desired.
If the table does not exist, it generates a warning message.
/* create fake data */
data testdat;
length lib $8 table $32;
input lib $ table $;
datalines;
work test1
work test2
work test3
work doesnotexist
;
run;
/* create 3 data sets */
data work.test1 work.test2 work.test3;
input var1 var2 var3;
datalines;
1 34 8
2 54 5
12 5 6
;
run;
/* end create data */
%let VarTable=work.testdat;
%let VarField=var2 var3;
data _null_;
set &VarTable;
dsname=catx('.',lib,table);
if exist(dsname) then do;
call execute("proc sort data=" || strip(dsname) || "; by &VarField; run;");
end;
else do;
put "WARNING: The data set does not exist: " lib= table=;
end;
run;
Upvotes: 2