转换 space 分隔字符串以用于 SAS PROC SQL IN 语句与 SQL 服务器

Converting space delimited string for use in SAS PROC SQL IN statement with SQL Server

我有一个宏函数,定义如下:

%MACRO Data_Load( Years );
    LIBNAME CCDW_LIB 
            ODBC 
            CONNECTION=SHAREDREAD 
            COMPLETE="DRIVER=SQL Server Native Client 11.0;SERVER=&CCDW_Server_Name;Trusted_Connection=Yes;DATABASE=&CCDW_Data_DB;"
            SCHEMA="&CCDW_Data_Schema"
            PRESERVE_TAB_NAMES=YES 
            PRESERVE_COL_NAMES=YES
            ;
    /* Server and database details obscured for obvious reasons */

    PROC SQL NOPRINT;
        CREATE TABLE WORK.TABLE1 AS 
            SELECT ID
                 , VAL1
            FROM CCDW_LIB.TABLE1
            WHERE YR IN ( &Years )
         ;
    QUIT; RUN;
%MEND;

当我将其作为 %Data_Load( 2018 ) 调用时出现错误,因为 YR 实际上被定义为 VARCHAR 而不是 NUMERIC。因此,我尝试在 WHERE 子句 (WHERE YR IN ( %SepList( &Years, nest=Q ) )) 中添加对 SepList 的调用,但这会出现语法错误,即使 MPRINT 语句是格式正确的 SQL 语句。如果我在 PROC SQL 调用之前将“2018”放入宏变量中,然后使用该变量,则 SQL 语句运行良好。事实上,我添加以下内容只是为了看看它们是否相同。

    %LET Years_IN='2018';
    %LET Years_IN1=%SepList( &Years, nest=Q );
    %Log( "Years_IN = [&Years_IN]");
    %IF &Years_IN1=&Years_IN %THEN %DO;
        %Log("They Match");
    %END;
    %ELSE %DO;
        %Log("The DONT Match");
    %END;

我想使用SepList,因为调用程序可能需要一年多的时间。知道我做错了什么吗?我是 运行 SAS 9.4 TS Level 1M5 X64_10PRO 如果重要的话。

尝试添加以下自定义函数,cquote()。它将 space 分隔的列表转换为单独引用的逗号分隔列表。例如,2012 2013 2014 将转换为 '2012','2013','2014'

将它保存在您的自定义函数工具箱中是一个很棒的函数。您不必使用 proc fcmp,但它会阻止您拥有充满 %sysfunc().

的巨大宏变量

如果您收到有关字符串太长的错误消息,这是 9.4M5 中的错误,并且存在 hotfix。您可以安全地忽略该错误。

proc fcmp outlib=work.funcs.funcs;
    function cquote(str $) $;
        length result 767;
        result = cats("'",tranwrd(cats(compbl(str))," ", "','"),"'");
        return (result);
    endsub;
run;

options cmplib=work.funcs;

%let years = 2012 2013 2014;
%let yearcq = %sysfunc(cquote(&years.));

我假设您正在使用 Richard DeVenezia 出色的函数式实用程序宏 %seplist: https://www.devenezia.com/downloads/sas/macros/index.php?m=seplist.

请注意,当您指定 nest=Q 时,它会引入一些宏引用。

每当 MPRINT 日志看起来不错但出现错误,并且正在进行宏引用时,请尝试明确取消引用。 (SAS 应该会自动取消引用,但并非总是如此)。

所以尝试:

WHERE YR IN (%unquote(&Years))

您还可以将宏定义的最后一行更改为:

%unquote(&emit)

以便它在返回值之前取消引用该值。