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

Escaping 提示管理器是否转义字符?,escaping,sas,prompt,Escaping,Sas,Prompt,我正在处理一个SAS程序,我创建了一个提示,允许用户输入逗号分隔的值列表。然后在中使用这些值,其中在子句中。问题是提示管理器似乎在转义引号,不知何故,导致了奇怪的错误消息 为了显示错误,我创建了以下示例数据集: DATA Work.Birds; LENGTH Category $ 20 CommonName $ 27 ; INPUT Category $ 1-20 Comm

我正在处理一个SAS程序,我创建了一个提示,允许用户输入逗号分隔的值列表。然后在
中使用这些值,其中在
子句中。问题是提示管理器似乎在转义引号,不知何故,导致了奇怪的错误消息

为了显示错误,我创建了以下示例数据集:

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的提示,并将值的数量设置为“Single Value”:

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

日志输出鸟类的以下信息:

"'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
子句,我都会遇到相同的错误。)

然后我试着用下面的代码输入“猕猴桃”、“水禽”:

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,但没有用。

试试这个:

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

我认为它的工作原理与我的测试所预期的一样“取消报价”是处理这类问题的众多简便技巧之一。

它奏效了!提示管理器是否添加引号?为什么它们不出现在
%PUT
语句中?(我对SAS比较陌生……请原谅我的无知)它本身并没有添加引号;它(显然)添加的是转义该值的不可打印字符。可能与%str()或%nrstr()的功能类似。不要担心无知,在这个领域我并不比你领先多少;每次SAS-L发布关于宏引用的帖子时,我几乎马上就迷路了。你太棒了。这让我和一位同事疯狂了两个小时。你知道这个“特性”的任何文档吗?我对PromptManager一无所知(我主要使用非EG SAS)。这可能是一种安全功能(这样提示管理器中的时髦字符不会导致意外结果)。%如果你在谷歌上搜索“宏引用”,NRSTR/etc将被大量覆盖;有大量文档/论文/困惑的人。据我所知,提示管理器提示本质上是存储过程提示的变体。因此,这可能足以用于您的目的的文档:。如果您只对引号(函数)感兴趣,它还建议使用比%UNQUOTE稍安全/更好的方法。