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