提示管理器是否转义字符?

时间:2013-05-20 21:06:16

标签: escaping sas prompt

我正在开发一个SAS程序,我创建了一个提示,允许用户输入以逗号分隔的值列表。然后在WHERE IN子句中使用这些值。问题是提示管理器似乎以某种方式转义引号,导致奇怪的错误消息。

为了显示错误,我创建了这个示例数据集:

DATA Work.Birds;

    LENGTH  Category    $   20
            CommonName  $   27
            ;

    INPUT   Category    $   1-20
            CommonName  $   22-48
            ;

DATALINES;
Ostriches            Common Ostrich
Ostriches            Greater Rhea
Cassowaries and Emus Southern Cassowary
Cassowaries and Emus Dwarf Cassowary
Kiwis                Brown Kiwi
Kiwis                Little Spotted Kiwi
Waterfowls           Horned Screamer
Waterfowls           Magpie-goose
Penguins             Emperor Penguin
Penguins             King Penguin
RUN;

现在,使用%LET语句,我可以为特定的鸟类编写一个或多或少的动态查询:

%LET BirdCategories = 'Kiwis', 'Penguins';

%PUT "&BirdCategories.";

PROC SQL NOPRINT;
    CREATE TABLE Work.SelectedBirds AS
    SELECT      *
    FROM        Work.Birds
    WHERE       Category IN ( &BirdCategories. )
    ;
QUIT;

此代码将以下内容打印到日志中:

"'Kiwis', 'Penguins'"

它还会创建一个包含四个记录的数据集。

现在,我尝试使用提示管理器创建一个提示符,其中包含official documentation中的说明。目标是使用提示替换单个%LET行,而不添加任何其他代码

所以我创建了一个名为BirdCategories的提示符,并将Number of Values设置为“Single Value”:

Screen-shot of first tab

Screen-shot of second tab

然后我再次运行程序(这次评论%LET语句):

Sceen-shot of prompt

日志为BirdCategories输出以下内容:

"'Kiwis', 'Waterfowls'"

但我的SQL语句中出现错误:

43             PROC SQL NOPRINT;
44                 CREATE TABLE Work.SelectedBirds AS
45                 SELECT      *
46                 FROM        Work.Birds
47                 WHERE       Category IN ( &BirdCategories. )

           _
           22
           200
ERROR 22-322: Syntax error, expecting one of the following: a quoted string, a numeric constant, a datetime constant, 
              a missing value, (, -, SELECT.  

ERROR 200-322: The symbol is not recognized and will be ignored.

48                 ;
NOTE: PROC SQL set option NOEXEC and will continue to check the syntax of statements.
49             QUIT;

(无论我使用PROC SQL还是使用DATA子句WHERE IN,我都会遇到相同的错误。)

然后我尝试使用以下代码输入Kiwis", "Waterfowls

PROC SQL NOPRINT;
    CREATE TABLE Work.SelectedBirds AS
    SELECT      "&BirdCategories."
    FROM        Work.Birds
    ;
QUIT;

应该创建两列,但我得到了这个:

One column with embedded quotes rather than two columns

如果我用SYMPUT设置宏变量,如下所示:

DATA _NULL_;    
    CALL SYMPUT( 'BirdCategories', 'Kiwis", "Penguins' );
RUN;

我按预期得到两列:

two columns

我看不到它,但提示管理员必须以某种方式逃避我的引用字符。有什么想法发生了什么?我试过我的google-fu无济于事。

1 个答案:

答案 0 :(得分:2)

试试这个:

PROC SQL NOPRINT;
    CREATE TABLE Work.SelectedBirds AS
    SELECT      *
    FROM        Work.Birds
    WHERE       Category IN ( %unquote(&BirdCategories.) )
    ;
QUIT;

我认为它的测试结果符合预期。 %UNQUOTE是处理这些东西的众多方便技巧之一。