在SAS中的Proc SQL中使用宏变量

时间:2014-05-02 16:35:44

标签: sql postgresql sas proc sas-macro

为表模式和表名定义了两个宏变量,它们在SAS的proc sql语句中使用(对Amazon RedShift的postgresql接口),无法正确读取sql语句。

%let table_schema = 'sales';
%let table_name = 'summary_table';

proc sql;
connect to ODBC(DSN='redshift_db', user=masteruser password='*pwd');
create table column_names as
select * from connection to odbc(
select distinct(column_name) as col_name from information_schema.columns where table_schema = &table_schema and table_name = &table_name;
);

create table dt as
select * from connection to odbc(
select * from &table_schema..&table_name;
);

QUIT;

第一个表创建会抛出错误:

错误:CLI描述错误:错误:列“summary_table”不存在于列中;

“summary_table”确实存在。

第二个表创建会引发错误:

错误:CLI描述错误:错误:“'sales'”或附近的语法错误;没有使用该句柄执行查询

也无效。

2 个答案:

答案 0 :(得分:1)

检查语法。

查看ERROR: column "summary_table" does not exist in columns;

这就是名为“columns”的名为“summary_table”的列不存在于名为“columns”的表上。 where子句试图比较2列,而不是列和字符串。

编写没有宏的查询并使其工作。然后尝试将宏放入。

这是PostGreSQL ODBC驱动程序的语法问题,而不是SAS。

答案 1 :(得分:1)

之前我没有使用PostGreSQL驱动程序,但我知道不同的DB处理报价的方式不同。可能是PostGreSQL需要双引号而不是单引号。如果是这种情况,那么我会改变你的代码:

%let table_schema = sales;
%let table_name = summary_table;

proc sql;
connect to ODBC(DSN='redshift_db', user=masteruser password='*pwd');
create table column_names as
select * from connection to odbc(
select distinct(column_name) as col_name from information_schema.columns where table_schema = "&table_schema" and table_name = "&table_name";
);

create table dt as
select * from connection to odbc(
select * from &table_schema..&table_name;
);

QUIT;

请注意,我已从%let语句中删除了单引号,并在第一个查询中的where子句中添加了双引号。

从宏变量中删除单引号也将修复您在第二次查询时遇到的语法错误,因为您有效地尝试执行以下操作:

select * from 'sales'.'summary_table';

......这很可能不正确。我再次没有使用PostGreSQL,所以我不能肯定地说 - 如果我错了,请纠正我,这是正确的语法。

最后,我建议在处理宏变量时,不要在字符串周围放置单引号。即

%let table_schema = 'sales'; * AVOID THIS WHEN POSSIBLE;

VS

%let table_schema = sales;   * USE THIS APPROACH WHEN POSSIBLE;

在使用宏变量的地方放置双引号,你可能会发现事情变得容易一些。当然,在某些情况下,您可能需要宏变量值的引号,但作为一般经验法则,我尽量避免这样做。