2

Here's an edit that reflects some progress made:

I have the following function that works:

proc fcmp outlib=mydir;
 function sqlWhere(interval $, myDate $) $;
 ...
 return("id");
 endsub;
quit;

This is tested and works fine. So I tried:

%macro sqlWhere(interval, myDate);
  &interval.("year") AS t
  &myDate.("someDateField") AS tt
%mend;
proc sql;
  CREATE TABLE test AS (
    SELECT %sqlWhere(t, tt)
    FROM myTable);
quit;

The top part runs fine when I run selection. However, the proc sql blows up and says I'm missing a comma. I'm confused because the function is returning " id " in other tests which should make the code work. The error says there is a missing comma on the "tt" part...

I'm attempting to make a dynamic query in SAS. I'm having a couple of issues and I'm not sure if what I want to do is possible. Also, sorry for deleting a prior question; I wanted to give a better explanation.

Say I have this code:

proc sql;
SELECT 
  YEAR(myDate) AS yr, 
  MONTH(myDate) AS mo,
  id
FROM
  myTable;
run;

I'm trying to make it conditional. This gives two problems. First, I can't get the basic syntax to work. Second, I can't get my custom function to create the proper string.

I want something like this:

%let a = sqlDate("month");
proc sql;
SELECT
  &a
FROM
  myTable;
run;

This structure doesn't work, even when I forgo the function and just enter

%let a = "YEAR(myDate) AS yr, MONTH(myMonth) AS mo, id";

Is something like this possible?

My second issue is how to construct the function itself, but I want to confirm I can even do something like this first. I'm basically putting an indicator in a master program that is either "day", "week", "month" or "year" and then telling the program to query SQL in a given way. Can I pass whole strings someway? Is it possible to build strings based on inputs in this manner?

4

1 回答 1

5

您的第一个问题是对 SAS 宏的误解。当你把这个:

%let a = "YEAR(myDate) AS yr, MONTH(myMonth) AS mo, id";

SAS 将输入您的查询:

"YEAR(myDate) AS yr, MONTH(myMonth) AS mo, id"

即:它将保留引号。如果您想在将函数放入 SAS 宏变量时“隐藏”诸如函数之类的东西,则必须使用 %str() 函数而不是“或”。因此,如果您要编写:

%str(YEAR(myDate) AS yr, MONTH(myMonth) AS mo, id);

你会有一些有用的东西。

回答你的第二个问题:这当然是可能的。但请记住一些非常重要的事情:任何宏函数、宏变量定义或对开放代码中的宏变量的调用,都会在您的 SAS 代码运行之前被解释和替换。如果您有一个依赖于 SAS 数据步骤或过程的结果的宏变量/函数,则需要将其封装在宏函数中:其中的所有内容仅在运行时被解释和替换。

编辑 回答您的评论:这主要是我传递的一般建议,因为您似乎不熟悉 SAS 宏。在某些情况下,您可能会得到奇怪的结果,看起来您的宏变量没有设置/更改,如果您不知道,这可能会令人沮丧。(我们都是第一次遇到它;))

In your specific case, if we assume you have made an sqldate macro that returns the appropriate select part, you're probably best off putting it immediately into the query. 例如:

%macro sqldate(period);
    &period.(mydate) as period
%mend;
/*note no semicolon, since a macro function is basically the same as saying: resolve this piece of macro code and add the result directly to my written code.*/

proc sql;
    select %sqldate(month)
    from mytable;
quit;
/*also note: you end proc sql with a quit statement instead of run*/
于 2013-07-12T22:03:54.083 回答