3

我正在开发一个 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'"

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

现在我尝试根据官方文档中的说明使用提示管理器创建提示。目标是在不添加任何额外代码%LET的情况下用提示替换单行。

所以我创建了一个名为 BirdCategories 的提示并将值的数量设置为“单值”:

第一个选项卡的屏幕截图

第二个选项卡的屏幕截图

然后我再次运行程序(这次注释掉%LET语句):

提示截图

日志为 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;

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

一列嵌入引号而不是两列

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

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

我得到了预期的两列:

两列

我看不到它,但提示经理必须以某种方式转义我的引号字符。有什么线索吗?我试过我的 google-fu 无济于事。

4

1 回答 1

2

尝试这个:

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

我认为它按我的测试预期工作。%UNQUOTE 是处理这些东西的许多方便技巧之一。

于 2013-05-20T21:24:38.433 回答