【问题标题】:Need catx macro function - catx is limited to 200 characters in proc sql需要 catx 宏功能 - catx 在 proc sql 中限制为 200 个字符
【发布时间】:2016-08-12 11:53:35
【问题描述】:

这可能是一个愚蠢的问题,但我找不到示例。 案例如下:

proc sql;
   create table set1 as select catx('<', field1, field2 ....) as need_field
   from table;
quit;

使用此代码字段,need_field 的长度会缩短为 200,因此它可以按照文档中的说明进行预测:

CATX 函数返回一个值给一个变量,或者返回一个值 一个临时缓冲区。从 CATX 函数返回的值 具有以下长度:

•WHERE 子句和 PROC SQL 中最多 200 个字符

•DATA 步中最多 32767 个字符(WHERE 子句除外)

•从宏处理器调用 CATX 时最多 65534 个字符

我不想使用数据步骤。你能帮我用宏处理器构建代码吗? (第三种方式)。谢谢!

【问题讨论】:

    标签: sas sas-macro proc-sql


    【解决方案1】:

    如果指定了length=catx 似乎可以返回超过 200 个字符,但所有数据必须适合列。否则你会得到空值。

    证明:

    data test;
       length a b c $400;
       a = repeat('A',300);
       b = repeat('B',300);
       c = repeat('C',300);
       output;
       a = repeat('A',350);
       b = repeat('B',350);
       c = repeat('C',350);
       output;
    run;
    
    proc sql;
       create table want as
       select catx('<', a, b, c) as temp_list length=1000
       from test;
    quit;
    
    data _null_;
       set want;
       a = length(temp_list);
       put a=;
    run;
    

    在文档中也有这样的:

    如果 CATX 在临时缓冲区中返回一个值,则 缓冲区取决于调用环境,以及缓冲区中的值 在 CATX 完成处理后可以截断。在这种情况下,SAS 不会将有关截断的消息写入日志。如果 变量的长度或缓冲区不够大,无法包含 连接的结果,SAS 执行以下操作:

    • 在 DATA 步和 PROC SQL 中将结果更改为空白值

    • 将警告消息写入日志,说明结果是 截断或设置为空白值,具体取决于调用 环境

    • 在日志中写入说明函数调用的位置并列出导致截断的参数
    • 在 DATA 步中将 _ERROR_ 设置为 1

    【讨论】:

      【解决方案2】:

      您可以创建自己的宏函数%CATX。 使用宏可以生成代码,在这种情况下使用%catx(&lt;, name, sex, name) 我生成了strip(name)||"&lt;"||strip(sex)||"&lt;"||strip(name),这与常规catx function 所做的非常相似。 带有parmbuff 选项的宏采用所有参数并将它们放入一个名为syspbuff 的宏变量中。

      %macro catx / parmbuff;
          %let comma = %eval(%index(&syspbuff., %str(,))+1);
          %let separator=%scan(&syspbuff., 1, %str(%(%),));
          %let syspbuff=%substr(&syspbuff., &comma., %eval(%length(&syspbuff.)-&comma.));
          %let result = strip(%sysfunc(tranwrd(%bquote(&syspbuff.), %str(,), %str(%)||"&separator."||strip%())));
          &result. 
      %mend catx;
      
      proc sql;
          create table a as
          select %catx(<, name, sex, name) as var
          from class;
      quit;
      

      【讨论】:

      • 这个代码块将极大地受益于对其工作原理的解释。
      • 我不知道你为什么要做这样的事情,但无论如何这在数字上都会失败。
      • @Joe 例如,如果 catx 真的只返回 200 个字符,那么您必须自己编写 substr(field1) || '&lt;' || substr(field2) || '&lt;' ... '&lt;' || substr(fieldn) 或使用此宏为您生成它。是的,它会在数字上失败。它仍然可以调整为数字或发送到 %catx put(numeric,format) 而不是数字。
      • 如果catx真的不行(确实行),那我就用FCMP写一个函数。
      • FCMP 函数通常性能很差,所以有时最好使用宏。
      【解决方案3】:

      有一个方便的技巧,您可以删除 cats 列并将其称为计算列。

      使用sashelp.class查看此示例

       proc sql;
        create table want(drop=temp_list) as
        select catx('<', repeat(name,200),repeat(name,200)) as temp_list length=1024,
            put((calculated temp_list),$400.) as need_field length=400
        from sashelp.class
        ;
      quit;
      

      示例 2:

      data a; 
      length a $1000; 
      a = repeat("A", 1000);
      run;
      
      proc sql; 
      create table b(drop=temp) as select catx('<', a, a) as temp length=2024,
         (calculated temp) as b length=5000 from a; 
      quit;
      

      希望对你有帮助

      【讨论】:

      • 您不需要创建另一个列。检查我的回答。
      • 我真的不喜欢这个解决方案。这是非常 hacky/噱头,如果其他人出现并且必须使用代码,则不清楚你为什么要这样做,他们很容易破坏它。
      • ...或者...您可以通过根据 fl0r3k 的答案定义长度来以正确的方式进行操作。
      猜你喜欢
      • 1970-01-01
      • 2022-01-17
      • 2017-08-07
      • 1970-01-01
      • 1970-01-01
      • 2012-03-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多