BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
Santt0sh
Lapis Lazuli | Level 10

Hi All,

 

I am trying to update a table where the Country code 3 column is missing or null using the below macro. Kindly find the partial log after the macro;

 

I believe there is some issue with the way have written this macro because every time I run this macro I need to run it a couple of times to update all the missing records.

Kindly suggest.

 

options Symbolgen Mlogic Mprint;

%macro ints;
Proc sql ;
select Count(*) into :dnts from cre.FSC_COUNTRY_DIM Where
UPPER(country_code_3)=' ';
quit;

%put &dnts.;

%if &dnts. eq 0 %then
%do;
%put Note:Country DIM NOT EMPTY;
%end;
%else
%do;
%put &dnts.;

%do i=1 %to &dnts.;

Proc sql noprint;
select PARTY_NUMBER, STREET_COUNTRY_CODE into :pty_num1 -: pty_num&i.,
:cnty_cde1 -:cnty_cde&i. from cre.FSC_COUNTRY_DIM where
UPPER(country_code_3)=' ';
quit;
%put PARTY_NUMBER&i.==>> &&cnty_cde&i.;

proc sql noprint;
update cre.FSC_COUNTRY_DIM set country_code_3="&&cnty_cde&i." where
PARTY_NUMBER="&&pty_num&i." and UPPER(country_code_3)=' ';
quit;
%put country_code_3&i.;

%end;
%end;
%mend;

%ints;

=========================================================

LOGS:

 

SYMBOLGEN: Macro variable I resolves to 7
SYMBOLGEN: Macro variable PTY_NUM7 resolves to 0000000000xxxxxXXXXXYY
MPRINT(INTS): update cre.FSC_COUNTRY_DIM set country_code_3="XXX" where PARTY_NUMBER="0000000000xxxxxXXXXXYY" and
UPPER(country_code_3)=' ';
NOTE: 1 row was updated in CRE.FSC_COUNTRY_DIM.
MPRINT(INTS): quit;
NOTE: PROCEDURE SQL used (Total process time):
real time 0.00 seconds
cpu time 0.01 seconds

MLOGIC(INTS): %PUT country_code_3&i.
SYMBOLGEN: Macro variable I resolves to 7
country_code_37
MLOGIC(INTS): %DO loop index variable I is now 8; loop will iterate again.
MPRINT(INTS): Proc sql noprint;
SYMBOLGEN: Macro variable I resolves to 8
SYMBOLGEN: Macro variable I resolves to 8
MPRINT(INTS): select PARTY_NUMBER, STREET_COUNTRY_CODE into :pty_num1 -: pty_num8, :cnty_cde1 -:cnty_cde8 from
cre.FSC_COUNTRY_DIM where UPPER(country_code_3)=' ';
MPRINT(INTS): ;
MPRINT(INTS): quit;
NOTE: PROCEDURE SQL used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds

MLOGIC(INTS): %PUT PARTY_NUMBER&i.==>> &&cnty_cde&i.
SYMBOLGEN: Macro variable I resolves to 8
SYMBOLGEN: && resolves to &.
SYMBOLGEN: Macro variable I resolves to 8
WARNING: Apparent symbolic reference CNTY_CDE8 not resolved.

 

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
Tom
Super User Tom
Super User

No need for to query twice to know how many macro variables you want to create.  SAS will stop when it runs out of observations.  And it will tell you how many it found in the automatic macro variable SQLOBS.

 

Here is a cleaned up version of your macro with some extra protection against special characters in the macro variables.

%macro ints;
%local i dnts party country;

proc sql noprint;
  select distinct 
         PARTY_NUMBER
       , STREET_COUNTRY_CODE
    into :pty_num1-
       , :cnty_cde1-
  from cre.FSC_COUNTRY_DIM 
  where country_code_3=' '
;
%let dnts=&sqlobs;

%if &dnts. = 0 %then %do;
  %put NOTE: No empty values of COUNTRY_CODE found.;
%end; 
%else %do i=1 %to &dnts.;
  %let party = %sysfunc(quote(%superq(pty_num&i),%str(%'))) ;
  %let country = %sysfunc(quote(%superq(cnty_cde&i),%str(%'))) ;

update cre.FSC_COUNTRY_DIM 
  set country_code_3=&country
  where party_number=&party
    and country_code_3=' '
;
%end;

quit;

%mend;

%ints;

But really it looks like you just want to run this query.

proc sql noprint;
update cre.FSC_COUNTRY_DIM 
  set country_code_3=STREET_COUNTRY_CODE
  where country_code_3=' '
;
quit;

View solution in original post

3 REPLIES 3
tarheel13
Rhodochrosite | Level 12

Did you try writing it outside the macro prior to macrotizing it? 

Quentin
Super User

Hi,

 

You might be better off describing the big picture of what you're doing.  My guess is there is non-macro solution.

 

Just glancing at the code, and not really understanding what it's doing, I would think that:

Proc sql noprint;
select PARTY_NUMBER, STREET_COUNTRY_CODE into :pty_num1 -: pty_num&i.,
:cnty_cde1 -:cnty_cde&i. from cre.FSC_COUNTRY_DIM where
UPPER(country_code_3)=' ';
quit;

Should be before the %do block.  And maybe it should be:

Proc sql noprint;
select PARTY_NUMBER, STREET_COUNTRY_CODE into :pty_num1 -: pty_num&dnts.,
:cnty_cde1 -:cnty_cde&dnts. from cre.FSC_COUNTRY_DIM where
UPPER(country_code_3)=' ';
quit;

But again, if this is basically a data update problem, you might be better off with a MERGE or UPDATE step rather than writing values to macro variables and then writing them back to a dataset.

 

The Boston Area SAS Users Group (BASUG) is hosting our in person SAS Blowout on Oct 18!
This full-day event in Cambridge, Mass features four presenters from SAS, presenting on a range of SAS 9 programming topics. Pre-registration by Oct 15 is required.
Full details and registration info at https://www.basug.org/events.
Tom
Super User Tom
Super User

No need for to query twice to know how many macro variables you want to create.  SAS will stop when it runs out of observations.  And it will tell you how many it found in the automatic macro variable SQLOBS.

 

Here is a cleaned up version of your macro with some extra protection against special characters in the macro variables.

%macro ints;
%local i dnts party country;

proc sql noprint;
  select distinct 
         PARTY_NUMBER
       , STREET_COUNTRY_CODE
    into :pty_num1-
       , :cnty_cde1-
  from cre.FSC_COUNTRY_DIM 
  where country_code_3=' '
;
%let dnts=&sqlobs;

%if &dnts. = 0 %then %do;
  %put NOTE: No empty values of COUNTRY_CODE found.;
%end; 
%else %do i=1 %to &dnts.;
  %let party = %sysfunc(quote(%superq(pty_num&i),%str(%'))) ;
  %let country = %sysfunc(quote(%superq(cnty_cde&i),%str(%'))) ;

update cre.FSC_COUNTRY_DIM 
  set country_code_3=&country
  where party_number=&party
    and country_code_3=' '
;
%end;

quit;

%mend;

%ints;

But really it looks like you just want to run this query.

proc sql noprint;
update cre.FSC_COUNTRY_DIM 
  set country_code_3=STREET_COUNTRY_CODE
  where country_code_3=' '
;
quit;

SAS Innovate 2025: Call for Content

Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!

Submit your idea!

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 3 replies
  • 554 views
  • 0 likes
  • 4 in conversation