Update an oracle table with data from another table in SAS - sql

I am trying to run the following piece of code to update table summary from data in click_summ table.
data temp(index=(comp=(card_number package_sk)));
set click_summ(where=(^missing(e_1st_click_dt)));
keep card_number package_sk e_1st_click_dt;
run;
data summary(drop=new_date) ;
set summary;
set temp(rename=(e_1st_click_dt= new_date) in=a) key=comp;
if a then do;
e_1st_click_dt = min(e_1st_click_dt,new_date);
end;
else
_ERROR_ = 0; /*No need for IORC errors*/
run;
This particular piece of code is throwing an error saying:
ERROR: The ORACLE table SUMMARY has been opened for OUTPUT. This table already exists, or there is a name conflict
with an existing object. This table will not be replaced. This engine does not support the REPLACE option.
What is the work around for the same? This question is related to a question I raised earlier (Summerizing a table in SAS)

Just change the table name from summary to something else and try..am not sure whether we can use summary as a table name since proc summary is there...not sure but try and see

As error-message says, you can't replace oracle table in DATA-step. The workaround of it would be:
1) To do all data manipulations in an interim SAS-dataset;
2) Delete all rows in an original Oracle table using PROC SQL ... DELETE ...;
3) Add new data (interim dataset) to empty Oracle table using PROC APPEND.

data temp;
set click_summ(where=(^missing(e_1st_click_dt)));
keep card_number package_sk e_1st_click_dt;
run;
data summary(drop=new_date) ;
modify summary temp(rename=(e_1st_click_dt= new_date) in=a);
by card_number, package_sk;
if a then do;
e_1st_click_dt = min(e_1st_click_dt,new_date);
end;
else
_ERROR_ = 0; /*No need for IORC errors*/
run;
Modify was the key. This will work fine with Oracle tables as well. And pretty fast too.

Related

Is there a way to nest a sql statement in a SAS IF/THEN/DO function?

So I have a SAS job that is scheduled to run and update a table regularly. I'm trying to add a functionality that drops the oldest month from the table when it is updating on the first day of a new month. Right now it looks like this:
PROC sql;
create table DropOldMonth as
select *
from ret.ServiceGFR_Impact;
create table DropOldMonth2 as
select *
from DropOldMonth
where date <> 'Jan 2020';
data _null_;
IF FirstDayofMonth = &todaysDate THEN DO;
proc sql;
drop table ret.ServiceGFR_Impact;
data ret.ServiceGFR_Impact;
set work.DropOldMonth2;
END;
run;
But I get this error:
ERROR 117-185: There was 1 unclosed DO block.
right below the Proc sql statement. I assume it's because there's a proc sql statement before and END statement to the DO function. However I need it to drop that table when that IF condition is true.
You may want to edit it in place instead of dropping it:
data ret.ServiceGFR_Impact;
set ret.ServiceGFR_Impact;
where date <> 'Jan 2020';
run;
make sure you have a backup before running it

How to use SAS data set brought to SQL Server temporary table and use with another temp table to join,update

Using SAS Enterprise Guide Version 7.1 64 bit.
I cannot create base tables in SQL Server thus can only create temporary table for data processing.
I am also pulling data over from a SAS data set to a global temporary table as(the SAS data set is teradata table pushed to sas-(step2). I need to update holiday table.
I also cannot see how many records are updated in the log (if there is a way to get it, it will be helpful as that way i know the code is working) - I have the sastraceloc but that is not showing update counts in a table.
I finally need to update ##t1 (step4) table created in step 1 with fields from ##holidays table (step2), how do I code this? Am I using the execute, proc sql combination correctly?
Step #1
LIBNAME tmpdta ODBC DATAsrc=datasrcname INSERTBUFF=32767
USER='uid' PASSWORD="pwd" connection=shared;
LIBNAME loc '/c/folder/data';
PROC SQL exec noerrorstop;
CONNECT TO odbc as test(DSN=datasrcname USER='uid' PASSWORD="pwd" connection=shared;
connection=shared);
execute
(create table ##t1
id int,
name varchar(50),
address varchar(100)
)by test;
-- end of 1
step #2
data tmpdt.'##holidays'n;
set loc.holidayexpns;
run;
step #3
proc sql;
connect using tmpdt;
execute
(
update u SET
fee=0,
month=5
FROM tmpdt.##holidays u
)by tmpdt;
step #4
PROC SQL exec noerrorstop;
CONNECT TO odbc as test(DSN=datasrcname USER='uid' PASSWORD="pwd" connection=shared;
connection=shared);
execute
(
update xyz
set a.fee=b.fee,
a.month=b.month
from tmpdt.##holidays h
join ##t1 xyz on
h.id=xyz.id
)by test;
The execute native-query will not know the SAS reference tmpdt., tmpdt will be known to your user login only if on the SQL Server side you have access to a catalog of like name. Did you mean to indicate tempdb ?
Per documentation
Any return code or message that is generated by the DBMS is available in the macro variables SQLXRC and SQLXMSG after the statement completes.

SAS SQL create table depending on macro variable result

I am struggling with creating a new table in proc sql SAS depending on macro variable result.
1) I want to check if necessary table exists.
2) If it exists then I want to create a new table with given parameters.
3) If it doesn't exist I want to create a new table with different parameters.
I think I know how to check if table exists (0 or 1 in log results):
%let tex1 = %sysfunc(exist(Base.pk_&monthP1));
%put tex1 = &tex1.;
But I do not know how to implement this result into proc sql statement.
I need sth like this:
proc sql;
create table test as
select case when &text1 = 0 then select ...
else
select ...
end ;
quit;
Thank you in advance for suggested solutions.
So if both tables have the same structure then the only part of the SQL code that needs to change is the FROM clause. It is probably easier to conditionally set a macro variable to the name to use and replace the name of the dataset with a reference to the macro variable.
select var1,varb, ....
from &dsname.
Now the problem becomes one of just setting the macro variable. You could do that with macro logic. But you could also just do that with data step logic.
data _null_ ;
if exist("Base.pk_&monthP1") then call symputx('dsname','table1');
else call symputx('dsname','table2');
run;
proc sql;
... from &dsname. ...

Analyze_Compensation in oracle

Can anyone please tell me for what purpose analyze_compensation is used in oracle?
I got this term in a code in bulk collect. PFB the link:
http://www.oracle.com/partners/campaign/o28plsql-095155.html
Suppose you want to print all the rows and columns of table i.e(Select * from table_name;
) in PL/SQL
THEN in that case :-
dbms_output.put_line() wont be able to print the table data when there is more than one row... Hence we use analyze_compensation() .
It is a procedure , which you need to declare in DECLARE BLOCK of PL/SQL
analyze_compensation is used to print the whole table data i.e Select * from table_name;

how to append all tables with their table name in SAS

I'm trying to append all the tables(same structure) in the work library into one data set. But I need to have a new column name which can indicate the table name.
I tried two methods:
macro array and do over:
PROC APPEND BASE=_dupout DATA=dup_&dataset. FORCE;
RUN;
Proc SQL:
PROC SQL;
SELECT MEMNAME, catx('.', libname, MEMNAME) INTO : MEMNAMES SEPARATED BY ' '
from dictionary.tables
where libname='WORK';
quit;
DATA DUP_OUT;
SET &MEMNAMES.;
RUN;
but neither of those I can find a way add a new column (table name). Maybe it is a very simple question? I'm stuck..please help...
Very close, use the INDSNAME option in your SET statement.
DATA DUP_OUT;
SET &MEMNAMES. INDSNAME=SOURCE;
DSET=SOURCE;
RUN;