我在MS SQL Server中有一个表格如下:
ID, Code
01, A
02, A
03, B
04, C
...
并在SAS中定义为
LIBNAME MSSQLDB ODBC
CONNECTION=SHAREDREAD
COMPLETE='Description=OIPE DW (Dev);DRIVER=SQL Server Native Client 11.0;SERVER=Amazon;Trusted_Connection=Yes;DATABASE=OIPEDW_Dev;'
SCHEMA='dbo'
PRESERVE_TAB_NAMES=YES
PRESERVE_COL_NAMES=YES;
我有一个SAS数据集,其格式与MSSQLDB(ID和代码变量)相同,但只是整个数据库的一个子集。
我想做以下事情:
PROC SQL NOPRINT;
/* If SASDS contains just codes A and B, CodeVar=A B
SELECT DISCTINCT CODE INTO :CodeVar SEPARATED BY ' ' FROM SASDS;
QUIT;
/* seplist is a macro that wraps each code in a quote */
%LET CodeInVar=%seplist( &CodeVar, nest=%STR(") );
PROC SQL;
DELETE * FROM MSSQLDB WHERE CODE IN (&CodeInVar);
/* Should execute DELETE * FROM MSSQL WHERE CODE IN ('A','B');
QUIT;
问题是这会对& CodeInVar宏变量中的值产生语法错误。
知道如何在IN语句中将宏变量值传递给SQL Server吗?
答案 0 :(得分:2)
我认为你在这里有一些问题;希望其中一些只是转录错误。
首先,这不会做任何事情:
PROC SQL;
DELETE * FROM MSSQLDB WHERE CODE IN (&CodeInVar);
/* Should execute DELETE * FROM MSSQL WHERE CODE IN ('A','B');
QUIT;
MSSQLDB是你的libname,而不是表;你需要在这里将它定义为MSSQLDB.dbname。也许这只是一个复制错误。
从根本上说,你键入的内容没有明显的错误。我建议首先确定你的宏变量是否有任何问题。在那里放一个%put语句:
%put &codeinvar.;
查看输出结果。这是你想要的吗?如果没有,那么修复那个部分(可能是宏)。
我想说有很多更好的方法可以做到这一点。首先,您不需要添加宏来添加逗号或引号或任何内容。
PROC SQL NOPRINT;
/* If SASDS contains just codes A and B, CodeVar=A B */
SELECT DISCTINCT cats("'",CODE,"'") INTO :CodeVar SEPARATED BY ',' FROM SASDS;
QUIT;
这应该让你和codevar完全按照你想要的那样[即'A','B'
]。
其次,由于您使用的是LIBNAME而不是通过SQL,因此请考虑使用SQL语法而不是完全使用SQL语法。
proc sql;
delete from MSSQLDB.yourtable Y where exists
(select 1 from SASDS S where S.code=Y.code);
quit;
这有时会更快,具体取决于具体情况(也可能更慢)。如果代码具有高频率,则首先使用PROC FREQ或SQL查询对其进行汇总。