My goal is to create a table in library abc using data within a remote server (i.e. my organization's data warehouse):
libname abc 'C:/Users/xxx/Desktop/SAS';
The above runs successfully, and then I am able to see and access library abc on the explorer window on the left side.
Then, I submit the following:
proc sql;
connect to db2(database = aaa user=&user. password=&pw.);
create table abc.srv_table_1 as
select *
from srv.table_1
;
quit;
The creation fails and outputs the following in the log:
ERROR: Library abc does not exist
What am I missing here?
Libref to non-existent
You will get a does not exist NOTE when a libname statement creates a libref to a non-existent library (i.e. folder or directory)
SQL will issue a NOTE: about stopping for errors when an invalid libref is used. Not an error that matches what you see.
25 libname abc 'c:\temp\abc';
NOTE: Library ABC does not exist. <------- NOTE:, not ERROR:
26
27 proc sql;
28 create table abc.xyz as select * from sashelp.class;
29 quit;
NOTE: The SAS System stopped processing this step because of errors.
Also, librefs are always uppercased by SAS, so I am not sure why your message shows both an ERROR: and a lowercase "abc".
Missing libref (unassigned)
You will see an ERROR:, but not the one you report seeing.
36 proc sql;
37 create table pqr.xyz as select * from sashelp.class;
ERROR: Libref PQR is not assigned. <----- ERROR:
38 quit;
NOTE: The SAS System stopped processing this step because of errors.
Related
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;
I'm having basically the same issue as the following post:Proc Data sets argument error- Error 22-322 expecting a name
But the answer didn't solve my problem.
%let _EFIERR_ = 0; /* set the ERROR detection macro variable */
libname indata "E:\el30053_54_55\el30053-postprocessor\output\files";
/* Format HYPO1001 variables */
PROC datasets library=INDATA;
MODIFY INDATA.hypo1001
/* Format section. */
format HYPOR1;
/* Should not need to edit anything below. */
run;
quit;`
Essentially, I have several datasets in the library INDATA. One of them is called hypo1001. Bottom line, I need to rename some of the variables in the dataset, but the rename statement isn't working because there are a few variables with invalid formats. So now I'm trying to fix the formats, but it doesn't seem to be working. From what I can tell, my syntax is correct, but I have very limited experience with SAS that doesn't usually extend much beyond just converting xpt files to SAS format.
I'm getting the following errors in the log:
ERROR 22-322: Expecting a name.
ERROR 201-322: The option is not recognized and will be ignored.
The libref you used to define the library should not be included in the member name that you use in the MODIFY statement. Try this example:
data class; set sashelp.class; run;
proc datasets nolist lib=work;
modify class ;
format name ;
run;
quit;
We currently use the %runquit macro function as detailed here (http://analytics.ncsu.edu/sesug/2010/CC07.Blanchette.pdf). The %runquit macro is shown below. It basically stops running any more SAS code when an error is encounterd, and can be used as a replacement for both the run and quit statements:
%macro runquit;
; run; quit;
%if &syserr %then %abort cancel;
%mend;
Because using the outobs statement in proc sql triggers a system error (even when the nowarn option is specified) it means we are unable to use the %runquit macro when we need to use the outobs= option.
The below example will generate the following warning message:
proc sql noprint outobs=3 /*nowarn*/;
create table tmp as
select age, count(*) as freq
from sashelp.class
group by 1
order by 2 desc
;
%runquit;
WARNING: Statement terminated early due to OUTOBS=3 option.
Thank you SAS for the completely unnecessary warning. The behaviour is obviously expected because I explicitly wrote code to ask for it. I don't see warnings given when we specify inobs= and outobs= on a set statement. Why does proc sql get the special treatment?
Is there any way to disable the warning issues by the outobs= option in proc sql? Alternatively, is there another way to limit the output rows from proc sql that will not generate an error?
Assuming you are okay with the full SQL statement executing, you can get around this with a data step view that contains the obs limitation.
proc sql noprint ;
create table tmp as
select age, count(*) as freq
from sashelp.class
group by 1
order by 2 desc
;
%runquit;
data tmp_fin/view=tmp_fin;
set tmp(obs=3);
%runquit;
Or make the SQL statement a view and use the data step to make the data set.
proc sql noprint ;
create view tmp_view as
select age
, count(*) as freq
from sashelp.class
group by 1
order by 2 desc
;
quit;
data tmp;
set tmp_view(obs=3) ;
run;
This might be one of your options considering I/O is not a huge constraint, here the reset outobs= option with nowarn does the trick but at IOs cost.
proc sql;
create table test as
select * from sashelp.class;
reset outobs=10 nowarn;
create table test1 as
select * from sashelp.class;
quit;
SAS has a 32 character limit for table- and column-names. I have a scenario where I want to select from Table A and join with Table B (where Table B has a name above 32 characters). If I try to write this in PROC SQL, I get an error saying that Table B has a name exceeding 32 characters.
Anyone know how I can get arround this?
Assuming this is working with a non-SAS DBMS, like SQL Server, you should use passthrough SQL to process the select, as this works with the RDBMS's syntax and doesn't have the 32 character limitation.
IE:
proc sql;
connect to oledb (... init string ... );
create table work.mydata as
select * from connection to oledb (
... sql server or whatever syntax ...
);
quit;
You also could ask the DBA to construct a view that had a < 32 character long name.
It is illegal for a SAS table to have more than 32 characters, you will have to rename the physical file. If you are reading a database table, you can do so using SQL passthrough like this:
proc sql;
connect to odbc(dsn=mydsn user=xxxx pwd=yyy);
select * from connection to odbc
(select * from my_table_with_a_very_Very_Very_Long_name);
disconnect from odbc;
quit;
SAS can't work with a "table" with that long name. You'll have to rename the file.
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.