BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
David_Billa
Rhodochrosite | Level 12

I have the macro program as below. Now I want to write a code between execute statement and create table Libname.&prompt_tble_name to check the number of observation in &schema_temp..&prompt_tbl_name and if it's greater than 0 then only execute next step otherwise just put a note in the log. I was asked not to create separate macro for this.

 

%macro test;
/* macro variable definitions code will be here and then below code*/
execute(
        create or replace table &schema_temp..&prompt_tbl_name as
          select distinct &current_distinct_var_list
          from &schema_temp..&source_tbl
        ;
      ) by database
            
      create table Libname.&prompt_tble_name as
        select * from connection to database(
          select *
          from &schema_temp..&prompt_tbl_name;
        )
      ;
%mend;
%test;

I can test the number of observations using below method but I'm not certain how to use the &totobs to execute the next step which is  'create table libname.&prompt_tble_name'

data _NULL_;
 if 0 then set &schema_temp..&prompt_tbl_name nobs=n;
 call symputx('totobs',n);
 stop;
run;
%put no. of observations = &totobs;
1 ACCEPTED SOLUTION

Accepted Solutions
Tom
Super User Tom
Super User

If you just had PROC SQL create a SAS dataset then it already knows how many observations it wrote and placed that value into the automatic macro variable SQLOBS.  So just use that macro variable to test.  If you also want to trap when the create step failed for some reason and so SQL OBS did not get updated set it to zero before the create step.

%let sqlobs=0;
create table WORK.t_&prompt_tbl_name as
        select * from connection to database(
          select distinct &current_distinct_var_list
          from &schema_temp..&source_tbl
        )
      ;

%if &sqlobs %then %do;
...

If you want to test another SAS dataset that you have not just created with an PROC SQL SELECT statement then you can use the NOBS= option of the SET statement to get the count without actually reading the whole table.

data _null_;
  call symputx('nobs',nobs);
  stop;
  set WORK.t_&prompt_tbl_name(drop=_all_) nobs=nobs;
run;  

NOTE: The DROP= dataset option will make sure there is no name conflict with variable used to store the NOBS= results.

View solution in original post

8 REPLIES 8
yabwon
Amethyst | Level 16

Do a double check because some databases may not offer correct value of:

nobs=n

when you are using libname to connect.

 

Bart

_______________
Polish SAS Users Group: www.polsug.com and communities.sas.com/polsug

"SAS Packages: the way to share" at SGF2020 Proceedings (the latest version), GitHub Repository, and YouTube Video.
Hands-on-Workshop: "Share your code with SAS Packages"
"My First SAS Package: A How-To" at SGF2021 Proceedings

SAS Ballot Ideas: one: SPF in SAS, two, and three
SAS Documentation



SASKiwi
PROC Star

With external databases you would be better off checking row counts using the actual database, for example count(*). What database are you using?

yabwon
Amethyst | Level 16

Try something like this:

%macro test(schema_temp,prompt_tbl_name);


execute(
        create or replace table &schema_temp..&prompt_tbl_name as
          select distinct &current_distinct_var_list
          from &schema_temp..&source_tbl
        ;
      ) by database

data _temp_;
  set &schema_temp..&prompt_tbl_name(obs=1);
run;
data _NULL_;
 call symputx('totobs',n);
 stop;
 set _TEMP_ nobs=n;
run;

%if &totobs > 0 %then %do;
      create table Libname.&prompt_tble_name as
        select * from connection to database(
          select *
          from &schema_temp..&prompt_tbl_name;
        )
      ;
%end;
%else
%do;
  %put NOTE: Zero obs!;
%end;


%mend;

%test(&schema_temp.,&prompt_tbl_name.)

Bart

_______________
Polish SAS Users Group: www.polsug.com and communities.sas.com/polsug

"SAS Packages: the way to share" at SGF2020 Proceedings (the latest version), GitHub Repository, and YouTube Video.
Hands-on-Workshop: "Share your code with SAS Packages"
"My First SAS Package: A How-To" at SGF2021 Proceedings

SAS Ballot Ideas: one: SPF in SAS, two, and three
SAS Documentation



Patrick
Opal | Level 21

To use dataset option nobs you would need to load the data into SAS. If the purpose is to only load the data into SAS if the table has more than zero observations then you need to count them on the database side. 

Code like below should work. 

I can't think of any reason why you shouldn't use multiple Proc SQLs. In doing so the code would become less convoluted in my opinion and you have also more certainty that timing between SAS, SAS Macro and the database is as you need it.

%macro test();
  %let n_obs=0;
  select n_obs into :n_obs trimmed 
  from connection to database
  ( 
    select count(*) as n_obs from &schema_temp..&prompt_tbl_name 
  );
  %if &n_obs> 0 %then
    %do;

    %end;
%mend;

%test();

 

Tom
Super User Tom
Super User

There is a disconnect here.  Your first step is running in some remote database.  Your example of how to check the number of observations is running in SAS. Are you sure they are checking the same table/dataset?

 

Are you saying that the macro variable SCHEMA_TEMP has both the name of the schema/database in the remote database and the name of a SAS libref that is pointing to the same schema/database?  (Note that would imply that the name of the schema in the remote database contains only letters, digits and underscores, does not start with a digit and is 8 characters or less long.) And if so are you sure that SAS can populate the NOBS= option of the SET statement for a table pulled from that remote database without actually pulling all of the data first?

 

If might be easier to test it explicitly.  So the logic flow would be something like:

connect .... ;

execute(
  create or replace table &schema_temp..&prompt_tbl_name as
    select distinct &current_distinct_var_list
    from &schema_temp..&source_tbl
) by database
;

%let nobs=0;
select nobs format=32. into :nobs trimmed
  from connection to database (
    select count(*) as nobs from &schema_temp..&prompt_tbl_name 
  )
;

%if &nobs %then %do;
create table Libname.&prompt_tble_name as
  select * from connection to database(
    select *
    from &schema_temp..&prompt_tbl_name;
  )
;
%end;

I do not see any need to create a new macro to introduce such simple logic. First if you already have the code in a macro you just need to modify it to add the new test.  And if you are not using a macro now there is no need to create a NEW macro just to use a %IF/%THEN/%DO/%END block as you can now run that in open SAS code.

David_Billa
Rhodochrosite | Level 12

If I want to identify the number of observations from SAS datasets instead of database table then do we have any other method other than select count(*) to fit here?

 

When  I tried the below method, I observed count(*)  step is executing for longer time. 

connect .... ;

create table WORK.t_&prompt_tbl_name as
        select * from connection to database(
          select distinct &current_distinct_var_list
          from &schema_temp..&source_tbl
        )
      ;

%let nobs=0;
select count(*)  format=32. into :nobs trimmed 
from WORK.t_&prompt_tbl_name
;

%if &nobs %then %do;
create table Libname.&prompt_tbl_name as
  select * from connection to database(
    select *
    from &schema_temp..&prompt_tbl_name;
  )
;
%end;
Tom
Super User Tom
Super User

If you just had PROC SQL create a SAS dataset then it already knows how many observations it wrote and placed that value into the automatic macro variable SQLOBS.  So just use that macro variable to test.  If you also want to trap when the create step failed for some reason and so SQL OBS did not get updated set it to zero before the create step.

%let sqlobs=0;
create table WORK.t_&prompt_tbl_name as
        select * from connection to database(
          select distinct &current_distinct_var_list
          from &schema_temp..&source_tbl
        )
      ;

%if &sqlobs %then %do;
...

If you want to test another SAS dataset that you have not just created with an PROC SQL SELECT statement then you can use the NOBS= option of the SET statement to get the count without actually reading the whole table.

data _null_;
  call symputx('nobs',nobs);
  stop;
  set WORK.t_&prompt_tbl_name(drop=_all_) nobs=nobs;
run;  

NOTE: The DROP= dataset option will make sure there is no name conflict with variable used to store the NOBS= results.

hackathon24-white-horiz.png

The 2025 SAS Hackathon has begun!

It's finally time to hack! Remember to visit the SAS Hacker's Hub regularly for news and updates.

Latest Updates

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 8 replies
  • 2111 views
  • 6 likes
  • 6 in conversation