12-09-2011 08:59 PM
SAS 9.2 on Windows
I need to ensure a dataset for a marketing mailout does not inadvertently contain customers already submitted previously. To accomplish this, I delete any customer numbers from today's mailout that are contained in any previous mailout.
To accomplish this, I was hoping to use a permanent data step view to concatenate all the previous mailouts, then use PROC SORT NODUPKEY on the concatenated view, then delete those records contained in the PROC SORT output.
However, I'm not getting the desired outcome. It appears that the dataset list is NOT dynamic, but in fact is compiled into the view at compile time. IMO this behaviour is a bug. Does anyone else agree before I raise a support track?
data d_1 d_2 d_3; x=1; run; data all/view=all; length dsname $32; set d_: indsname=dsn; dsname=scan(dsn,2); run; proc print data=all; run; data d_4; x=1; run; proc print data=all; run; proc delete data=d_2; run; proc print data=all; run;
The view does not print the d_4 data, and it fails if d_2 is deleted. If I select "describe view" in SAS Explorer, it indicates the set statement contains a dataset list, which I would have expected would be evaluated at run time, not compile time. If nothing else, it's very misleading.
12-09-2011 10:29 PM
I have little experience with dataset lists, which are a pretty new feature.
However, variable lists, an old feature, are evaluated at compile time, so I think I would expect the behavior you found.
I would use PROC SQL and tap DICTIONARY.TABLES to get the current list.
12-10-2011 09:48 AM
I'm not familiar with dataset lists either but, from your explanation, I wonder if you are deleting the correct records. I would think that you would want to delete any 'customer numbers' who end up in a dupout file created by a proc sort nodupkey run.
12-10-2011 11:58 AM
Scott - I am seeing the same behavior as you are. You will need to generate the list of datasets in another way. Such as:
proc sql noprint ;
select memname into :mlist separated by ' '
and substr(memname,1,2) = 'D_'
set &mlist indsname=dsn ;
12-11-2011 10:57 PM
VIEW only contains the information of QUERY ,it is static.
If you want it more robust, then use Tom's code to collect the existed datasets firstly, or use macro to detect it existence firstly.
%if %sysfunc(exist(class)) %then %do; class %end;
%else %if %sysfunc(exist(shoes)) %then %do; shoes%end;
12-20-2011 08:04 AM
Thanks for all the replies, much appreciated.
However, they all addressed *how* SAS works with respect to data step views, which I had already deduced. I was more interested in people's opinions of *how* they thought SAS should work.
I must admit I don't recall ever creating a data step view using a variable list but, as Howles said, the variable list in the data step view is static as defined at compile time. And the same behaviour holds for data set lists.
I know the data step view is a compiled object where the definition is compiled, but the data is dynamic and derived at run time. I guess the question is, should variable lists and data set lists in a data step view be dynamic as well? After all, it's just software; SAS could have created this to work in either way.
IMO, dynamic variable lists and data set lists would be very useful, but I admit it could also cause confusion / problems if the data set structure changed after the view was created. But, if I had to choose, I would make the variable lists and data set lists dynamic, where the data step view derives the list at runtime. I suspect the current functionality was just "easier" when data step views were first developed.
In any case, I find the "describe view" functionality to be misleading; I believe it should return the expanded lists as they were defined at compile time.
Regarding the various replies, I could either just redefine the view each time, rather than defining a permanent view, or use the dictionary tables. As suggested, I did choose to use the dictionary tables, as I found the generated code to be clearer. But the results are the same in both approaches.