需要 catx 宏功能 - catx 在 proc 中限制为 200 个字符 sql

Need catx macro function - catx is limited to 200 characters in proc sql

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

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

使用此代码字段 need_field 可切割至长度 200,因此它可以预测如文档所述:

The CATX function returns a value to a variable, or returns a value in a temporary buffer. The value that is returned from the CATX function has the following length:

•up to 200 characters in WHERE clauses and in PROC SQL

•up to 32767 characters in the DATA step except in WHERE clauses

•up to 65534 characters when CATX is called from the macro processor

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

有一个方便的技巧,您可以删除 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),0.) as need_field length=400
  from sashelp.class
  ;
quit;

示例 2:

data a; 
length a 00; 
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;

希望对您有所帮助

您可以创建自己的宏函数%CATX。 使用宏可以生成代码,在本例中使用 %catx(<, name, sex, name) 我生成了 strip(name)||"<"||strip(sex)||"<"||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;

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

证明:

data test;
   length a b c 0;
   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;

在文档中还有这个:

If CATX returns a value in a temporary buffer, the length of the buffer depends on the calling environment, and the value in the buffer can be truncated after CATX finishes processing. In this case, SAS does not write a message about the truncation to the log. If the length of the variable or the buffer is not large enough to contain the result of the concatenation, SAS does the following:

  • changes the result to a blank value in the DATA step, and in PROC SQL

  • writes a warning message to the log stating that the result was either truncated or set to a blank value, depending on the calling environment

  • writes a note to the log that shows the location of the function call and lists the argument that caused the truncation
  • sets _ERROR_ to 1 in the DATA step