【问题标题】:SAS Macro variable escaping apostrophe in variable name Proc HttpSAS 宏变量在变量名 Proc Http 中转义撇号
【发布时间】:2021-08-11 06:15:37
【问题描述】:

我已经为此工作了 3 天,并尝试了所有我能想到的方法,包括 %str()、%bquote()、translate() 和 tranwrd() 以用双撇号或 %' 替换单个撇号/p>

以下数据步骤和宏工作正常,直到我点击包含撇号的姓氏,例如奥布莱恩。然后,由于未闭合的左括号,我遇到了语法错误。下面的代码我留下了我认为最接近包含的 tranwrd 的代码。

非常感谢您提供的任何帮助。

%macro put_data (object1,id);
Proc http
method=“put”
url=“https://myurl/submissionid/&id”
in=&object1;
Headers “content-type”=“application/json”;
Run;
%mend;

data _null_;
Set work.emp_lis;
call execute(catt(‘%put_data(‘,’%quote(‘’{“data”:{“employeeName”:”’,tranwrd(employeeName,”’’”,”’”),’”}}’’),’,id,’)’));
run;

克雷格

【问题讨论】:

  • 请显示输入值。请显示适用于 O’Brien 值的 SAS 代码,不带任何宏或宏变量。
  • 为什么不使用 QUOTE() 而不是 TRANWRD() 来处理包含引号的引用值?
  • 您发布的代码有“智能”引号,而不是普通的单引号 ' 或双引号 " 字符。这就是造成您麻烦的原因吗?

标签: sas sas-macro


【解决方案1】:

只需使用实际引号,您就不必担心宏引用。

如果你的宏看起来像这样:

%macro put_data(object1,id);
proc http method="put"
  url="https://myurl/submissionid/&id"
  in=&object1
;
  headers "content-type"="application/json";
run;
%mend;

那么 OBJECT1 的值通常是带引号的字符串文字或文件引用。 (实际上还有其他形式。)看起来您正在尝试生成带引号的字符串。所以只需使用 QUOTE() 函数。

因此,如果您的数据如下所示:

data emp_lis;
  input id employeeName $50.;
cards;
1234 O'Brien
4567 Smith
;

然后您可以使用这样的数据步骤为每个观察生成一个宏调用。

data _null_;
  set emp_lis;
  call execute(cats
    ('%nrstr(%put_data)('
    ,quote(cats('{"data":{"employeeName":',quote(trim(employeeName)),'}}'))
    ,',',id
    ,')'
    ));
run;

您的 SAS 日志将如下所示:

NOTE: CALL EXECUTE generated line.
1    + %put_data("{""data"":{""employeeName"":""O'Brien""}}",1234)

NOTE: PROCEDURE HTTP used (Total process time):
      real time           2.46 seconds
      cpu time            0.04 seconds

2    + %put_data("{""data"":{""employeeName"":""Smith""}}",4567)

NOTE: PROCEDURE HTTP used (Total process time):
      real time           2.46 seconds
      cpu time            0.04 seconds

【讨论】:

    【解决方案2】:

    我发现我的代码存在 tranwrd 语句向后的问题,需要将其移至 proc sql create table 语句。我还需要将 &object1 包含在 %bquote 中。这是最终有效的代码。 在 tranwrd 中创建表换行变量时,如下所示。

    tranwrd(employeeName, "'","''")

    % macro put_data (object1,id);
    Proc http
    method=“put”
    url=“https://myurl/submissionid/&id”
    in=%bquote(&object1);
    Headers “content-type”=“application/json”;
    Run;
    %mend;
    
    data _null_;
    Set work.emp_lis;
    call execute(catt(‘%put_data(‘,’%quote(‘’{“data”:{“employeeName”:”’,employeeName,’”}}’’),’,id,’)’));
    run;
    
    

    【讨论】:

      【解决方案3】:

      在 SAS 宏中构造或传递 json 字符串可能会出现很多问题。 Proc JSON 将从数据中生成有效的 json(在文件中),而该文件又可以指定为 Web 服务使用的输入。

      例子:

      data have;
        length id 8 name $25;
        input id& name&;
      datalines;
      1  Homer Simpson
      2  Ned Flanders
      3  Shaun O'Connor
      4  Tom&Bob 
      5  'X Æ A-12'
      6  Goofy "McDuck"
      ;
      
      %macro put_data (data,id);
      
      filename jsonfile temp;
      
      proc json out=jsonfile;
          export &data.(where=(id=&id));
      
          write values "data";
          write open object;
              write values "name" name;
          write close;
      run;
      
      proc http
          method="put"
          url="https://myurl/submissionid/&id"
          in=jsonfile
      ;
          headers "content-type"="application/json";
      run;
      
      %mend;
      
      data _null_;
          set have;
          call execute(cats('%nrstr(%put_data(have,',id,'))'));
      run;
      

      【讨论】:

      • 嗨,理查德,感谢您的及时回复和非常有用的信息/代码。我发现我的代码中的问题是我的 tranwrd 语句是向后的,需要将它移到表创建 proc sql 中。此外,我需要将我的 &object1 包装在 %bquote 中。我会尽快上传。感谢您的反馈和帮助。
      猜你喜欢
      • 2017-10-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多