我正在开发一个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”:
然后我再次运行程序(这次评论%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无济于事。
答案 0 :(得分:2)
试试这个:
PROC SQL NOPRINT;
CREATE TABLE Work.SelectedBirds AS
SELECT *
FROM Work.Birds
WHERE Category IN ( %unquote(&BirdCategories.) )
;
QUIT;
我认为它的测试结果符合预期。 %UNQUOTE是处理这些东西的众多方便技巧之一。