3

When I write:

proc sql;
    select count(*) into :out from sashelp.cars;
quit;

Does the macro variable out become a global or local variable?

Parfait
  • 104,375
  • 17
  • 94
  • 125
Victor
  • 16,609
  • 71
  • 229
  • 409
  • 2
    Your example code doesn't show a macro. Thus it could only be global. But it's not clear from the question if you understand what is meant by local vs global macro vars in SAS. The rules for macro scope are the same with SQL select into: as they are with a plain %let statement. – Quentin Nov 15 '15 at 23:53
  • Doing a `%put _global_;` and `%put _local_;` will show it. – Snorex Feb 28 '17 at 15:27

3 Answers3

8

It depends. Let's put together a test macro and see what happens

%macro test();
proc sql noprint;
select count(*) into :x from sashelp.cars;
quit;
%put IN MACRO: &x;
%mend;

options nosource nonotes;

%symdel x;

%test();

%put Out MACRO: &x;

%let x=2;

%put Out MACRO: &x;

%test();

%put Out MACRO: &x;

Creates:

IN MACRO:      428
WARNING: Apparent symbolic reference X not resolved.
Out MACRO: &x
Out MACRO: 2
IN MACRO:      428
Out MACRO:      428

So at the beginning, there was no X macro variable. The %test() macro populated a local variable. It was not available outside the macro.

After that, we set %let x=2 making X be a global variable. Then we execute the %test() macro and see that X keeps its value outside of the %test() macro.

So if it exists globally, it continues to exist and is overwritten. If it doesn't exist globally, it continues to not exist globally.

DomPazz
  • 12,415
  • 17
  • 23
  • Good answer. It might also be worth mentioning `%local`, because if `%local x;` is the first line in the definition of macro `%test` then this will also affect the results. – Amir Nov 16 '15 at 09:50
  • This is only half of the answer. You should also mention how `%global` affects the behavior as well. – Robert Penridge Nov 16 '15 at 15:39
2

Let's take a look at the documentation to answer this compeltely.

The documentation for SQL INTO clause in the Macro language dictionary says:

Macro variables created with INTO follow the scoping rules for the %LET statement. For more information, see Scopes of Macro Variables.

So, we click on that link, and find this page - How Macro Variables are Assigned and Resolved and this page - Examples of Macro Variable Scopes.

The first page has a nice tree diagram showing the decisions SAS makes when assigning or creating a macro variable, and that might be sufficient to understand this.

The second page has some good examples and explanations:

When the macro processor executes a macro program statement that can create a macro variable (such as a %LET statement), the macro processor attempts to change the value of an existing macro variable rather than create a new macro variable. The %GLOBAL and %LOCAL statements are exceptions.

There are some very good examples on that page; what it boils down to, though, is simple. If there is already an existing macro variable with that name, it will assign the value to that macro variable, wherever that variable is - in the scope tree of the current macro, anyway. (So, a single macro executing has two symbol tables to look in: local, and global. A macro called by another macro has three: local, local to the calling macro, and global. Etc.)

However, there are a pair of related exceptions: when you specify the table to use, with %local or %global. Either of those statements referencing a macro variable before your %let or select into will cause any following statements to set that particular version - local or global - and then you're safe for sure.

Joe
  • 62,789
  • 6
  • 49
  • 67
  • Last paragraph is not really a HOWEVER. What the `%local` and `%global` statements do is let you create a macro variable explicitly as local or global. Then the `%let` will use the existing macro variable as you noted in the quoted explanation. – Tom Nov 16 '15 at 15:53
-1

It depends on where you define this marco variable, if you define it in a macro program, it is a local macro variable, otherwise it is a global macro variable.

Shenglin Chen
  • 4,504
  • 11
  • 11
  • 1
    This is wrong. If your macro program defines it as `%global` then it will be a global var, not a local var. – Robert Penridge Nov 16 '15 at 15:37
  • But OP did not mention that macro variable has been defined as global macro variable first before use proc sql to define macro out. – Shenglin Chen Nov 16 '15 at 16:03
  • It is irrelevant what the OP said. As your answer stands, it is stating incorrect information. – Robert Penridge Nov 16 '15 at 17:07
  • So, you set condition!? – Shenglin Chen Nov 16 '15 at 18:16
  • So I was going to edit your answer to 'correct' it, but it would basically be a completely new/different answer, which doesn't seem like the right way to handle it. I'd advise that you take a close look at Joe's answer which is the most precise, and read the links provided thoroughly. – Robert Penridge Nov 16 '15 at 18:43