- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
I am doing a call execute from a data set to execute a macro and return the gsqlrc(which contains sqlxrc) and gsqlmsg(which contains sqlxmsg). However, the 2 assignment statements are getting a null value. I look at the value in the macro and it is not null. Any ideas?
data final_validation;
set dbtblnames_complete;
tablename=newtblname1;
call execute('%nrstr(%deterifcolsexist(&var1,&var2,' || strip(newtblname1) || '));');
call execute('%nrstr(%tstuniqvalid(' || strip(newtblname1) || '))');
sqlerrcode=symget('gsqlrc');
sqlerrmsg=symget('gsqlmsg');
Accepted Solutions
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Or revisit your program and see if a function via PROC FCMP would be more appropriate than a macro.
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Call Execute stacks code for execution after the Data Step terminates.
You probably need the Dosubl Function.
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Or revisit your program and see if a function via PROC FCMP would be more appropriate than a macro.
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Thank you . I did use DOSUBL but i get ERROR 180-322: Statement is not valid or it is used out of proper order. do you see the error? I have not figured it out.
data final_validation;
set dbtblnames_complete;
tablename=newtblname1;
call execute('%nrstr(%deterifcolsexist(&var1,&var2,' || strip(newtblname1) || '));');
rc = dosubl('%nrstr(%tstuniqvalid(' || strip(newtblname1) || '))');
/*%put &gsqlrc &gsqlmsg;*/;
sqlerrcode=symget('gsqlrc');
sqlerrmsg=symget('gsqlmsg');
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
no nothing that is there in that call is required for the macro
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
ok here is what I am trying to accomplish:
This macro gets called:
%macro tstuniqvalid(crnttblname);
proc sql;
connect to teradata as xxxx (username=&xxuser. password=&xxpass. tdpid=&xxWP_TDPID. mode=teradata fastload=yes);
create table unique_validcustid as
select * from connection to xxxx (
select hist_ky_add
,count(*)
from (select cast(cust_id as decimal(15,0)) as cust_id_test
,cust_id
,cust_id_type
,cell_ky
,rank(cust_id || cust_id_type || cast(cell_ky as varchar(16))asc)as hist_ky_add
from &crnttblname) a
group by 1
having count(*) > 1
);
%global gsqlrc gsqlmsg;
%if &sqlxrc ne 0 %then
%do;
%put "Test load table for uniqueness and valid cust_id FAILED due to SQL error";
%let gsqlrc=&sqlxrc;
/*%put &=gsqlrc;*/
%let gsqlmsg=&sqlxmsg;
/*%put &=gsqlmsg;*/
data _null_;
call symput('gsqlrc',gsqlrc);
call symput('gsqlmsg',gsqlmsg);
%put "in the data step of tstuniqu";
%put &=gsqlrc "rc in the data step";
%put &=gsqlmsg "msg in the data step";
run;
%end;
and what i am trying to do in it is return the sql return code and message when it is not 0 (i e there is a sql error) . So that i can put it in a table.It is called from here: The symgets are where I am trying to assign the returned values to a table(final_validation);
data final_validation;
set dbtblnames_complete;
tablename=newtblname1;
call execute('%nrstr(%tstuniqvalid(' || strip(newtblname1) || '))');
rc = dosubl('%tstuniqvalid(' || strip(newtblname1) || ')');
sqlerrcode=symget('gsqlrc');
sqlerrmsg=symget('gsqlmsg');
put "Put data in the table";
put sqlerrcode;
put sqlerrmsg;
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Leave in only the DOSUBL.
I'm assuming you also just missed the %MEND end for your macro?
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
hi thank you the %MEND is there just did not put it in the post. I will make the other DOSUBL but I would not think one impacts the other, they are separate ......
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Passing values through macro variables is probable not what you want to do. Just have your macro insert observations into a table. You can then use the values from that table after all of the macro calls have finished.
%macro tstuniqvalid(crnttblname);
proc sql;
connect using xxxx ;
create table unique_validcustid as
select * from connection to xxxx (
select hist_ky_add
,count(*)
from (select cast(cust_id as decimal(15,0)) as cust_id_test
,cust_id
,cust_id_type
,cell_ky
,rank(cust_id || cust_id_type || cast(cell_ky as varchar(16))asc)as hist_ky_add
from &crnttblname) a
group by 1
having count(*) > 1
);
insert into final_validation(crnttblname,nobs,sqlxrc,sqlxmsg)
values ( "&crnttblname",&sqlobs,&sqlxrc,"%superq(sqlxmsg)" )
;
quit;
%mend;
* Connect to teradata ;
libname xxxx teradata username=&xxuser. password=&xxpass. tdpid=&xxWP_TDPID. mode=teradata fastload=yes;
* Create empty summary table ;
data final_validation;
length crnttblname $128 nobs 8 sqlxrc 8 sqlxmsg $256 ;
stop;
run;
* Call macro once for each table ;
data _null_;
set dbtblnames_complete;
call execute(cats('%nrstr(%tstuniqvalid)(',newtblname1,')'));
run;
You can now just print the dataset if you want to see any tables that caused errors.
proc print data=final_validation;
where sqlxrc ne 0;
run;
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
@Gayle wrote:
well it looks like it did not like the nrstr. I removed that however I still am not getting the expected return values . I get nulls(.)
Yes, tested it, DOSUBL does not like the %NRSTR. %NRSTR is also only needed in CALL EXECUTE to prevent premature execution of macro code.
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Start with something simple, and expand from there:
%macro test1(param);
%global ¶m.;
%let ¶m. = YYY;
%mend;
data _null_;
rc = dosubl('%test1(XXX)');
xxx = symget('XXX');
put xxx=;
run;
You will see that the DOSUBL method works in creating the macro variables, so that it can be returned by SYMGET.