I've created table from library called 'common' by using proc sql table is created with crdate by descending now I need to write macro to pick top one which is the latest dataset which is created in that library
Assuming your library contains SAS datasets (.sas7bdat), then the following will create a macro variable latest_dataset with the name of the latest dataset in the COMMON library, without the use of an actual macro:
proc sql noprint;
select memname into: latest_dataset
from dictionary.tables
where libname='COMMON'
having crdate=max(crdate);
%put &=latest_dataset;
Related
I would like to create a new table with all tables contained within a library and the variables within each of those tables. I know I can use something like the below to get the table name but I cant find much on getting each variable. I have multiple libraries and each has potentially hundreds of tables. Any help really appreciated.
proc sql ;
create table mytables as
select *
from dictionary.tables
where libname IN ('WORK','SPDSWORK',etc)
order by memname ;
quit ;
Just use PROC CONTENTS with the special _ALL_ member name. Use the NOPRINT option to suppress the output and the OUT= option to name the dataset with the contents information.
proc contents data=mylib._all_ noprint out=contents;
run;
Use distionary.columns instead.
proc sql ;
create table mytables as
select *
from dictionary.columns
where libname IN ('SASHELP')
order by memname ;
quit ;
On the SAS server we have a library that contains thousands of datasets. I want to catalog the contents of a subset of these, all of which have names that begin with "prov". Can I use a wildcard to specify this?
I tried:
PROC CONTENTS DATA=library.prov*;
RUN;
But that just produces a log with this error message:
ERROR: File LIBRARY.PROV.DATA does not exist.
I also tried library.prov%, and that gave the same error.
There are over 100 datasets that start with "prov" so I really don't want to have to do them one at a time. Any ideas?
Depending on what information you want that the CONTENTS procedure produces you could just use the DICTIONARY metadata views.
proc sql ;
create table want as
select *
from dictionary.columns
where libname = 'LIBREF'
and memname like 'PROV%'
;
quit;
Use a WHERE data set option.
proc contents data=sashelp._all_ noprint out=class(where=(memname like 'CLASS%'));
run;
When you specify the keyword _ALL_ in the PROC CONTENTS statement, the step displays a list of all the SAS files that are in the specified SAS library.
Example :
PROC CONTENTS DATA=libref._ALL_ NODS;
RUN;
But to open only the datasets that begin with prov you can use the SQL and add CONTAINS to WHERE e.g:
proc sql ;
create table mytables as
select *
from dictionary.tables
where libname = 'WORK'
order by memname ;
quit ;
Now just run:
PROC CONTENTS DATA mytables;
RUN;
I may be using a different version of SAS check if you have the library SASHELP if so try this based on my note in your comment on the previous response you may see that this works out for you:
proc sql outobs=100;
create table see as
select distinct libname,memname,crdate,modate from sashelp.vtable
where libname='LIBRARY' and memname like 'PROV%'
order by memname;
quit;
Say I have the a library named mylib.
Within the mylib library, the following datasets are held:
mylib.data_yearly_2015
mylib.data_yearly_2016
mylib.data_yearly_2017
mylib.data_yearly_2018
mylib.data_yearly_2015
mylib.data_mtly_01JUN2015
mylib.data_mtly_01DEC2015
mylib.data_mtly_01JUN2016
mylib.data_mtly_01DEC2016
mylib.data_mtly_01JUN2017
mylib.data_mtly_01DEC2017
Now I need to write a macro that will specifically choose the latest data_mtly_xxxxxx table from the mylib library.
For example, in the current stage, it should choose mylib.data_mtly_01DEC2017
If, however, a new dataset gets added, for example mylib.data_mtly_01JUN2018, it would have to choose that table.
How can I go about doing this in SAS?
Get a list of all data sets
Get the date portion using SCAN() and INPUT()
Get max date.
Proc sql noprint;
Select max(input(scan(name, -1, ‘_’), date9.) ) into :latest_date
From sashelp.vtable
Where upcase(libname) = ‘MYLIB’ and upcase(memname) like ‘DATA_MTLY_%’;
Quit;
Now you should have the latest date value in a macro variable and can use that in your code.
%put &latest_date.;
If it looks like a number and not a date, you’ll need a format applied but you should be able to convert it using PUT().
Note: code is untested.
MY SITUATION
I hope all is well. I am currently undertaking a research project with deals with a lot a datasets placed under different libraries. I have created multiple %macro definitions which in turn has generated many output tables and utilised many input tables. These tables are saved under different libraries.
MY ISSUE:
My computer slows down when these datafiles are created. Clearing unwanted tables in every macro program session speedens up computational response.
My QUERY:
Is there a way to generate a list of input and output tables created either using PROC SQL or DATA steps by each macro program? Each MACRO PROGRAM has multiple %macros, once again from code readability purposes. Prefixing/suffixing the datafiles with 'IN' or 'OUT' statements does not help.
This would help me in data management.
You probably have two options: parsing a log file or making a snapshot of dictionary.tables before and after every macro call and extracting the differences. I would prefer an ( easier :)) second option, e.g. like
PROC SQL;
CREATE TABLE BEFORE AS SELECT CATS(libname,".",memname) AS fname FROM DICTIONARY.tables WHERE libname in ('WORK');
QUIT;
PROC SQL;
CREATE TABLE AFTER AS SELECT CATS(libname,".",memname) AS fname FROM DICTIONARY.tables WHERE libname in ('WORK') AND calculated fname not in (select fname FROM BEFORE);
QUIT;
I am trying to load SAS dataset into a teradata table using FASTLOAD utility. This works fine in some cases, but I want to separate the error tables and create them in my own/other database in teradata environment.
Could some one provide me the syntax (I do know it but it's not working) for how to make it possible?
Any method is fine either using proc sql command or proc append command. Thanks in advance.
You can use the LOGDB libname option to tell SAS into which database the log files should be created. By default they are created in the same database as the table being created (named as the target table named plus the three character suffixes you've discovered). Using the info provided in your comments, try this:
/* Delete any exisiting log files for table TPT_LD_TEST */
libname TPTLOAD TERADATA
SERVER=TDServ DATABASE=TPTLOAD
USER=tduser PASSWORD=tdpasswd1
;
proc delete data=TPTLOAD.TPT_LD_TEST_ET;
run;
proc delete data=TPTLOAD.TPT_LD_TEST_UV;
run;
proc delete data=TPTLOAD.TPT_LD_TEST_RS;
run;
libname TPTLOAD clear;
/* Define connection to target database */
LIBNAME TDSERV TERADATA
SERVER=TDServ
USER=tduser PASSWORD=tdpasswd1
LOGDB=TPTLOAD;
/* Truncate target table if necessary */
proc sql noprint;
delete from TDSERV.TPT_LD_TEST;
quit;
proc append base=TDSERV.TPT_LD_TEST(fastload=yes tpt=yes)
data=work.FastLoad;
run;
I added some code to delete any existing rows in the target table (a requirement for FASTLOAD).
If you have DROP TABLE and CREATE TABLE rights on your target database, it might be safer to drop and re-create the table so you can guarantee the structure and explicitly name the table index.
/* Delete target table if it exists */
proc delete data=TDSERV.TPT_LD_TEST;
run;
data TDSERV.TPT_LD_TEST
(fastload=yes tpt=yes
dbcreate_table_opts='primary index(index_column_name)'
)
set work.FastLoad;
run;
And in either case, be sure to remove any duplicate records from your source dataset; those will be written to your error files (as well as any records that fail other constraints).
PROC DELETE is a handy device because it will not create an error if the target table does not exist.