我使用以下 case 表达式来验证 var1 的值并将值分配给新变量 var1_val。数据集response_options_scan包含一个名为valid_values的列,其中包含从数据字典文件转置的var1的所有有效值。数据集response_options_select 包含一个名为requirement_status 的列,其中包含值“All Records”、“Required”,或诸如“var2 contains xyz”之类的条件(指示何时需要var1)。我试图选择在第三个条件中使用requirement_status,因为此代码在宏中使用来验证数十个变量,并且requirement_status中的条件不应进行硬编码。然而,当硬编码条件 request_status 与使用 select 语句时,我得到不同的结果。
硬编码有效并给出 var1_val 的正确值。
proc sql noprint;
create table validate_select_test
as select *
,case when var1 in (select valid_values from response_options_scan where variable="var1") then "var1 valid value"
when var1="" and (select requirement_status from response_options_select where variable="var1") in ("All Records", "Required") then "var1 invalid value: missing"
when var1="" and var2 contains 'XYZ' then "var1 invalid value: missing"
when var1="" then "var1 valid value: missing"
else "var1 invalid value"
end as var1_val format=$100.
from validate_select;
quit;
var1 | var2 | var1_val |
---|---|---|
A | var1 有效值 | |
ABC | var1 有效值:缺失 | |
ABC:XYZ | var1 无效值:缺失 |
使用 select 语句则不会。需要明确的是,response_options_select 中的requirement_status 值,其中variable="var1" 是“var 2 contains 'XYZ'”。如果 var2 不包含 XYZ,则 var1=missing 的记录的 var1_val 的值为“var1 有效值:缺失”。
proc sql noprint;
create table validate_select_test
as select *
,case when var1 in (select valid_values from response_options_scan where variable="var1") then "var1 valid value"
when var1="" and (select requirement_status from response_options_select where variable="var1") in ("All Records", "Required") then "var1 invalid value: missing"
when var1="" and (select requirement_status from response_options_select where variable="var1") then "var1 invalid value: missing"
when var1="" then "var1 valid value: missing"
else "var1 invalid value"
end as var1_val format=$100.
from validate_select;
quit;
var1 | var2 | var1_val |
---|---|---|
A | var1 有效值 | |
ABC | var1 无效值:缺失 | |
ABC:XYZ | var1 无效值:缺失 |
SQL 无法动态更改正在执行的语句。您将需要使用包含语言片段的控制数据来生成使用它们的源代码。
示例:
data response_options_select ;
infile datalines length=linelength;
length variable $32 requirement_status $200;
input variable& requirement_status& ;
datalines;;;;
var1 expr:var2 contains "XYZ"
var1 expr:var2 contains "pqr"
;;;;
%macro case_gen(control=, var=);
%local dsid index rc;
%local variable rq_type requirement_status;
%let dsid = %sysfunc(open(&control(
keep=variable requirement_status
where=(variable="&var" and requirement_status like 'expr:%')
)
));
%put %sysfunc(sysmsg());
%syscall set(dsid);
( 0 /* code gen */
%do %while (%sysfunc(fetch(&dsid))=0);
or /* code gen */ %substr(&requirement_status,6)
%end;
) /* code gen */
%let dsid = %sysfunc(close(&dsid));
%mend;
data have;
length var1 var2 $200;
var1 = '' ; var2 = '' ; output;
var2 = 'ABC'; output;
var2 = 'ABC:XYZ' ; output;
run;
proc sql;
create table want as
select
case
when missing(var1) and %case_gen(control=response_options_select, var=var1) then 'Invalid: Matched expression in control'
else 'yada yada yada'
end as var1_validation
from have
;
quit;
提交时将提交此代码,其中部分代码是生成的代码。
proc sql;
create table want as
select
case
when missing(var1) and
( 0
or var2 contains "XYZ"
or var2 contains "pqr"
)
then
'Invalid: Matched an expression in the select control data set'
else
'yada yada yada'
end as var1_validation
from have
;