Passing a value from Netezza back to SAS using a macro variable - sql

we're using SAS 7.13 HF1 (7.100.3.5419) (64-bit)
I'm currently looking at a post that shows how to pass a value from SAS to a database that you're connecting in to. Here is the example below. You can see they take the Macro variable StartDate and pass it into Teradata to be used in the query.
%let StartDate = 2016/01/01;
proc sql;
connect to teradata
(BULKLOAD=YES MODE=TERADATA user=&user. Password=&passwd.);
CREATE TABLE WorkTest.test AS
select * from connection to teradata
(
SELECT
TOP 10 *
FROM SomeCalendarData
WHERE SomeDate = %bquote('&StartDate.');
);
quit;
I want to go the other way.
How can I read a value from a similar query, only my DB is Netezza, and somehow pass it to a macro variable in SAS?
Thanks!

You would use the
SELECT <expression> INTO :<macro_var>'
statement. This is available in the PROC SQL query but not in the pass-through code, so it would look something like
proc sql;
connect to teradata
(BULKLOAD=YES MODE=TERADATA user=&user. Password=&passwd.);
select somedate into :my_macro_var from connection to teradata
(
SELECT somedate
FROM SomeCalendarData
WHERE id = 101;
);
quit;
See the docs here: http://support.sas.com/documentation/cdl/en/sqlproc/63043/HTML/default/viewer.htm#n1tupenuhmu1j0n19d3curl9igt4.htm

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 query SSMS via SAS EG ODBC connection while using data from WORK?

Is there a way to send a SAS dataset through a proc sql odbc query in SAS EG so that it can be taken in and used by SQL server?
ex)
SAS Data WORK.A contains 3 columns ID, col1, col2.
I have a table in Sql Management Studio environment with the same ID column.
I would like to (somehow) do as shown in Figure A below:
Figure A)
proc sql;
Connect to odbc("driver=SQL Server; database=SSMSDatabase; Server=SSMSServer");
create table WORK.B as
select * from connection to odbc
(
Select t1.*, t2.*
from SSMSTable1 t1
INNER JOIN WORK.A t2 ON t1.ID = t2.ID
);
disconnect from odbc;
quit;
This throws an obvious error in SAS as SSMS doesn't understand what WORK.A is... It's expecting pure SSMS code to be executed.
I have passed macro variables created in SAS through to SQL passthrough to be used in the WHERE statement like in figure B, but that has it's limitations (especially with macro character length) and is not as elegant as passing a whole table.
Figure B)
proc sql;
select cat("'",trim(ID),"'")
into :list1 separated by ","
from WORK.A;
quit;
%macro ODBCRun();
proc sql;
Connect to odbc("driver=SQL Server; database=SSMSDatabase; Server=SSMSServer");
create table WORK.B as
select * from connection to odbc
(
Select *
from SSMSTable1
WHERE ID IN (&list1.)
);
disconnect from odbc;
quit;
%mend;
%ODBCRun();
Any ideas would be helpful.
Create a temporary table in SQL Server, against which you can perform your later pass through query.
Example:
libname SS odbc
dbmstemp=yes
noprompt="driver=SQL Server; database=SSMSDatabase; Server=SSMSServer"
;
* upload SAS data into SQL Server;
proc delete data=ss.'#idlist'n;
run;
data ss.'#idlist'n;
set WORK.A;
run;
* Use uploaded data in pass through query;
proc sql;
connect using SS as REMOTE; * reuses connection libref made;
create table WORK.B as
select * from connection to REMOTE
(
select t1.*, t2.*
from
SSMSTable1 t1
INNER JOIN
#idlist t2
ON
t1.ID = t2.ID
);
disconnect from REMOTE;
quit;

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. ...

Sas process sql

I am trying to select from a SQL server table that both has dashes in the name and is greater than 32 characters.
I have tried pass through and quotes but no joy.
It's very unlikely that I could get a view produced and only have read access.
proc sql;
drop table poss_gw1;
create table poss_gw1 as ( select * from cdb.'''form_Garden_waste_service_AF-Form-59fb9946-0f6e-4cd9-‌​9b30-82fc5d96ec71'''‌​n as agg);
quit;
proc sql;
connect to odbc(dsn=FirmstepReporting user=myname pwd=mypwd);
Create table work.tmp_gw as select * from connection to odbc (select * from "'form_Garden_waste_service_AF-Form-59fb9946-0f6e-4cd9-9b30-‌​82fc5d96ec71'"n);
disconnect from odbc;
quit;
Any one have any ideas?
You need to use SQL Server syntax in the pass thru code.
create table work.tmp_gw as
select * from connection to odbc
(select *
from "form_Garden_waste_service_AF-Form-59fb9946-0f6e-4cd9-9b30-‌​82fc5d96ec71"
);
If your variable names are also not valid for SAS then you will need to change the name in the pass thru code also.
create table work.tmp_gw as
select * from connection to odbc
(select id
, "invalid-name" as valid_name
from "form_Garden_waste_service_AF-Form-59fb9946-0f6e-4cd9-9b30-‌​82fc5d96ec71"
);

Use PROC SQL to create keep list for columns

i need select colums whose names contains string '_fire'. Names can be obtained by statement select
proc sql;
create table x as select _name_
from work.x
where lowcase(_name_) like '%_fire'
;quit;
But i dont know, what to do next? I tried insert this data into variable, but then i get error: Invalid value for the KEEP option.
proc sql noprint;
select _name_
into :names
from work.x
where lowcase(_name_) like '%_fire';
quit;
DATA twowks1 ;
SET work.&tabulka. (KEEP = &names. ) ;
RUN;
can anyone help me? Thx
You're missing the separated by in your PROC SQL query.
However, I only get your error when &Names does not exist, so is there an error with your SQL Query?
*To generate your error;
%symdel names;
DATA twowks1;
SET work.&tabulka. (KEEP=&names.);
RUN;
Here is some that works as you're probably expecting.
*Works as expected;
proc sql noprint;
select _name_ into :names separated by " "
from work.x
where lowcase(_name_) like '%_fire';
quit;
DATA twowks1;
SET work.&tabulka. (KEEP=&names.);
RUN;