Macros for SAS Application Developers
https://github.com/sasjs/core
Loading...
Searching...
No Matches
mp_filtervalidate.sas
Go to the documentation of this file.
1/**
2 @file
3 @brief Checks a generated filter query for validity
4 @details Runs a generated filter in proc sql with the validate option.
5 Used in mp_filtercheck.sas in an fcmp container.
6
7 Built to support dynamic filtering in
8 [Data Controller for SAS®](https://datacontroller.io).
9
10 Usage:
11
12 data work.filtertable;
13 infile datalines4 dsd;
14 input GROUP_LOGIC:$3. SUBGROUP_LOGIC:$3. SUBGROUP_ID:8. VARIABLE_NM:$32.
15 OPERATOR_NM:$10. RAW_VALUE:$4000.;
16 datalines4;
17 AND,AND,1,AGE,=,12
18 AND,AND,1,SEX,<=,"'M'"
19 AND,OR,2,Name,NOT IN,"('Jane','Alfred')"
20 AND,OR,2,Weight,>=,7
21 ;;;;
22 run;
23
24 %mp_filtergenerate(work.filtertable,outref=myfilter)
25
26 %mp_filtervalidate(myfilter,sashelp.class)
27
28 @returns The SYSCC value will be 1008 if there are validation issues.
29 On an abort the message carries the reason and the clause that failed, so
30 the inputs are visible without reading the log.
31
32 @param [in] inref The input fileref to validate (generated by
33 mp_filtergenerate.sas)
34 @param [in] targetds The target dataset against which to verify the query
35 @param [out] abort= (YES) If YES will call mp_abort.sas on any exceptions
36 @param [out] outds= (work.mp_filtervalidate) Output dataset containing the
37 diagnostic message, if one exists. If this table contains any rows,
38 there are problems!
39
40 <h4> SAS Macros </h4>
41 @li mf_getuniquefileref.sas
42 @li mf_nobs.sas
43 @li mp_abort.sas
44
45 <h4> Related Macros </h4>
46 @li mp_filtercheck.sas
47 @li mp_filtergenerate.sas
48
49 @version 9.3
50 @author Allan Bowe
51
52**/
53
54%macro mp_filtervalidate(inref,targetds,abort=YES,outds=work.mp_filtervalidate);
55
56%mp_abort(iftrue= (&syscc ne 0 or &syserr ne 0)
57 ,mac=&sysmacroname
58 ,msg=%str(syscc=&syscc / syserr=&syserr - on macro entry)
59)
60
61%local fref1 flt_clause flt_msg;
62%let fref1=%mf_getuniquefileref();
63
64data _null_;
65 file &fref1;
66 infile &inref end=eof;
67 length flt_clause $4000;
68 retain flt_clause;
69 if _n_=1 then do;
70 put "proc sql;";
71 put "validate select * from &targetds";
72 put "where " ;
73 end;
74 input;
75 put _infile_;
76 putlog _infile_;
77 /* the generated clause, kept so a failure can name the inputs it was given -
78 the SQL message reports only the clashing data types */
79 flt_clause=cats(flt_clause,ifc(_n_>1,' ',''),strip(_infile_));
80 if eof then do;
81 put ";quit;";
82 call symputx('flt_clause',flt_clause,'l');
83 end;
84run;
85
86%inc &fref1;
87
88data &outds;
89 if &sqlrc or &syscc or &syserr then do;
90 REASON_CD='VALIDATION_ERR'!!'OR: '!!
91 coalescec(symget('SYSERRORTEXT'),symget('SYSWARNINGTEXT'));
92 output;
93 end;
94 else stop;
95run;
96
97filename &fref1 clear;
98
99%if %mf_nobs(&outds)>0 %then %do;
100 %if &abort=YES %then %do;
101 data _null_;
102 set &outds;
103 length flt_msg $4000;
104 call symputx('REASON_CD',reason_cd,'l');
105 /* the clause is reported with the reason: the SQL message says which
106 types clashed but not which inputs produced it */
107 flt_msg=catx(' ','Filter validation issues:',reason_cd
108 ,catx(' ','Clause: where',symget('flt_clause')));
109 call symputx('flt_msg',flt_msg,'l');
110 stop;
111 run;
112 %mp_abort(
113 mac=&sysmacroname,
114 msg=%superq(flt_msg)
115 )
116 %end;
117 %let syscc=1008;
118%end;
119
120%mend mp_filtervalidate;