I'm using a SAS access to oracle. and I want to see the query that SAS sends to Oracle.
assume that : oracle is the name of the oracle libname and local is the sas libname.
proc sql;
select *
from oracle.oracle_table ot
inner join local.sas_table st
on ot.customer_id = st.customer_id
;
quit;
I want to know if sas retrieves all data from the oracle table and then does the join or it's sending the list of the customer ids.
Thanks !
MK
Use sastrace to see how it's coming over from Oracle, and _method to see how they are being joined.
options sastrace=',,,d' sastraceloc=saslog;
proc sql _method;
select *
from oracle.oracle_table ot
inner join local.sas_table st
on ot.customer_id = st.customer_id
;
quit;
Related
I have metrics sas table like below
work.met_table
Metrics_Id Metrics_desc
1 Count_Column
2 Sum_Column
3 Eliminate_column
I wanna do something like doing while loop in T-sql
select count(*) :cnt_tbl from work.met_table
%let init_cnt = 1
while (&init_cnt = &cnt_tbl)
begin
select Metrics_desc into :met_nm
from work.met_table
where metrics_id = 1
Insert into some_sas_table
Select * from another table where Metrics_desc =&met_nm
/* Here I wanna loop all values in metrics table one by one */
end
%put &init_cnt = &int_cnt+1;
How this can be done in proc sql? Thanks in advance
If you want to dynamically generate code then use the SAS macro language.
But for your example there is no need to dynamically generate code.
proc sql ;
insert into some_sas_table
select *
from another_table
where Metrics_desc in (select Metrics_desc from work.met_table)
;
quit;
You can also do an explicit pass through. Send your native t-sql code to run on the database Server through SAS rather than bringing the data to the SAS application server to query it.
The example below is explained in details here.
PROC SQL;
CONNECT TO ODBC(DATASRC=SQLdb USER=&SYSUSERID) ;
/* Explicit PASSTHRU with SELECT */
SELECT *
FROM CONNECTION TO ODBC (
SELECT b.idnum o.[SSdatecol] AS mydate
FROM dbo.big_SS_table1 b
LEFT JOIN dbo.other_SStable o
ON b.idnum = o.memberid
WHERE o.otherdatecol >= '2014-10-06'
--This is a T-SQL comment that works inside SQL Server
) ;
;
DISCONNECT FROM ODBC ;
QUIT;
This how I configured my LibName
LIBNAME OrcaleSAS ORACLE USER=UserName PASSWORD=pwd*** PATH = '(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=host.unix.####.com)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=prod.tk.com)))'
And to fetch data below is the code I am using
PROC SQL;
connect using OracleSAS AS OracDB;
select * from connection to oracle
(select * from ENTITY_DATES_WK13);
disconnect from OracDB;
quit;
I am getting the error OracleSAS is not a SAS name & Error in the LIBNAME statement , I am fairly new to SAS..!!
connecting to oracle or any dbms can be done libname or by explicit pass through. Libname method is used to access oracle table(or any dbms) in SAS(tables are usually moved to SAS). Explicit method ( using connect statement) where in query is directly sent to Oracle(or dbms mentioned). This methods are not interchangeable for oracle(or anydbms) table and hence you got error.
below is libname method
LIBNAME OrcaleSAS ORACLE USER=UserName PASSWORD=pwd*** PATH =
'(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=host.unix.####.com)(PORT=1521))
(CONNECT_DATA=(SERVICE_NAME=prod.tk.com)))'
libname sastab "/whatever path/";
proc sql;
create table sastab.tablename as
select *
oratable.tablename
quit;
below is explicit pass through method
proc sql;
connect to oracle as myconn (user=smith password=secret
path='myoracleserver');
create table sastab.newtable as
select *
from connection to myconn
(select *
from oracleschematable);
disconnect from myconn;
quit;
The name you use for your library, called the libref, can only by 8 characters long.
OracleSAS is 9 characters.
Use something shorter.
When you set up a libname you don't need the Connect portion of the PROC SQL. You're mixing two methods of connecting to a SQL database into one.
Assuming your libname worked correctly you can query it the same as you would any other SAS table at this point:
PROC SQL;
create table want as
select * from ENTITY_DATES_WK13;
quit;
proc print data=want(obs=5);
run;
The other method is 'pass through' which means the query is passed fully to the server to run on that side. This means the inside query needs to be Oracle compliant and you can't use SAS functions or data.
At last I ended doing something like this..,
%let usr ="pradeep"
%let pwd ="******"
%let pth = "ORACLEPATH"
%put path: &path;
proc sql;
connect to oracle(user = &usr
password =&pwd
path =&pth buffsize=5000);
/* my code */
I am using Proc SQL to create Teradata views. I used Execute (pass through facility) and passed the column names as using variables. But the views which are getting created do not have the columns in the order which was passed into the query. They are getting created at any random order. Is there a way to fix this?
Using the method described here:
data tmp;
aa = 1;
db = 1;
ac = 1;
bb = 1;
run;
proc sql ;
select name into :VARLIST separated by ', '
from dictionary.columns
where libname = 'WORK'
and memname = 'TMP'
order by name ;
quit ;
proc sql ;
create table ordered as
select &VARLIST
from work.tmp ;
quit ;
Not familiar with Teradata per se, more used to working with SAS/DB2, but what if instead of using execute() you would use something like this -- this will create the view on the SAS side (which might not be what you're after, I'm not entirely sure).
proc sql;
connect to teradata (user=testuser password=testpass);
create view work.myView as
select * from connection to teradata
(select var1, var2, var3
from someTable);
quit;
I want write a passthrough query in SAS but I don't want to bring back the results and I want to store the results in Teradata.
In Teradata SQL I can do
create table db.table2 as (select
column1,
column2,
count(*) as cnt
from
db.table1
group by
column1, column2
having cnt = 1) with data primary index(column1, column2)
)
In SAS there is only examples of pass-through query that returns some results into SAS. In this case I just want to use SAS to create a table on Teradata without leaving the SAS interface (I can do this in Teradata Studio Express) but it breaks the workflow.
How do I do a "pass-through" without returning the results? The below doesn't seem to work. What's the right for what I want to do?
PROC SQL;
CONNECT TO TERADATA(user="user" password="pw" server ="Teradata.something.somehwere");
drop table teradata.sometable ;
DISCONNECT FROM TERADATA;
QUIT;
You need the EXEC statement:
PROC SQL;
CONNECT TO TERADATA(user="user"
password="pw"
server ="Teradata.something.somehwere");
EXEC( ) BY TERADATA;
EXEC( Commit ) BY TERADATA; /* this is needed if the above statement modifies the database in anyway) */
drop table teradataserver.sometable ;
DISCONNECT FROM TERADATA;
QUIT;
Within the brackets you can insert a Teradata SQL statement that will run on the DB and keep the results on the DB. So, in full:
PROC SQL;
CONNECT TO TERADATA(user="user"
password="pw"
server ="Teradata.something.somehwere");
EXEC(
create table db.table2 as
(
select
column1,
column2,
count(*) as cnt
from
db.table1
group by
column1, column2
having cnt = 1
) with data primary index(column1, column)
) BY TERADATA;
DISCONNECT FROM TERADATA;
QUIT;
For info, the BY part specifies which DB to process the statement on, if we were connecting to more than one DB within the SQL Procedure, e.g.
PROC SQL;
CONNECT TO TERADATA AS T1 (...);
CONNECT TO TERADATA AS T2 (...);
EXEC(...) by T1;
EXEC(...) by T2;
DISCONNECT FROM T1;
DISCONNECT FROM T2;
QUIT;
I have a dataset which has multiple obs per person. I want to have each single record showing the sum of a variable per person ID. However I do not want to group the data into single personal IDs. I hope the example below explains my question
I want to create the column in bold. How to do this? In SAS EG (or SAS if necessary)?
ID...Var1...SUM
X.....10.......30
X.....20.......30
Y.....20.......80
Y.....20.......80
Y.....40.......80
Z.....30.......30
You can do this using either proc sql or proc means
more info:proc means
proc sql
proc sql:
proc sql noprint;
create table new_table as
select distinct id, var1, sum(var_to_sum) as summed_var_name
from old_table
group by id
;
quit;
after rereading your question, using proc means you will need to merge var1 back in, better off using proc sql above.
proc means:
proc means data = old_table sum;
by id var1;
var var_to_sum;
output out = new_table sum;
run;