35%macro mp_getdbml(liblist=SASHELP,outref=getdbml,showlog=NO
39%
if %sysfunc(fileref(&outref)) > 0 %then %
do;
40 filename &outref temp;
43%let liblist=%upcase(&liblist);
47 select * from dictionary.tables
48 where upcase(libname) in (%mf_getquotedstr(&liblist))
49 order by libname,memname;
50%local tabinfo; %let tabinfo=&syslast;
53 select * from dictionary.columns
54 where upcase(libname) in (%mf_getquotedstr(&liblist))
55 order by libname,memname,varnum;
56%local colinfo; %let colinfo=&syslast;
59 select distinct upcase(cats(libname,
'.',memname)) into: dsnlist
65 select * from dictionary.indexes
66 where upcase(libname) in (%mf_getquotedstr(&liblist))
67 order by idxusage, indxname, indxpos;
68%local idxinfo; %let idxinfo=&syslast;
71%mp_getconstraints(lib=%scan(&liblist,1),outds=_data_)
72%local colconst; %let colconst=&syslast;
74%
do x=2 %to %sysfunc(countw(&liblist));
75 %mp_getconstraints(lib=%scan(&liblist,&x),outds=_data_)
76 proc append base=&colconst data=&syslast;
86 put
"// DBML generated by &sysuserid on %sysfunc(datetime(),datetime19.) ";
87 put
"Project sasdbml {";
88 put
" database_type: 'SAS'";
89 put
" Note: 'Generated by the mp_getdbml() macro'";
98 if first.libname then put
"TableGroup " libname
"{";
99 ds=quote(cats(libname,
'.',memname));
101 if last.libname then put
"}";
106 length curds
const col $39;
107 call missing (of _all_);
112%local x curds constraints_used constcheck;
113%
do x=1 %to %sysfunc(countw(&dsnlist,%str( )));
114 %let curds=%scan(&dsnlist,&x,%str( ));
115 %let constraints_used=;
119 length lab $1024 typ $20;
120 set &colinfo (where=(
121 libname=
"%scan(&curds,1,.)" and upcase(memname)=
"%scan(&curds,2,.)"
125 table='Table "'!!"&curds"!!'"{
';
129 lab=" note:"!!quote(trim(tranwrd(label,'"',"'")));
130 if upcase(format)=:'DATETIME
' then typ='datetime
';
131 else if type='char' then typ=cats('char(
',length,')
');
134 if notnull='yes
' then notnul=' not
null';
135 if notnull='no
' and missing(label) then put ' ' name typ;
136 else if notnull='yes
' and missing(label) then do;
137 put ' ' name typ '[
' notnul ']
';
139 else if notnull='no
' then put ' ' name typ '[
' lab ']
';
140 else put ' ' name typ '[
' notnul ',
' lab ']
';
144 data _data_(keep=curds const col);
145 length ctype $11 cols constraints_used $5000;
146 set &colconst (where=(
147 upcase(libref)="%scan(&curds,1,.)"
148 and upcase(table_name)="%scan(&curds,2,.)"
149 and constraint_type in ('PRIMARY
','UNIQUE
')
152 by constraint_type constraint_name;
154 column_name=upcase(column_name);
156 if _n_=1 then put / ' indexes {
';
158 if upcase(strip(constraint_type)) = 'PRIMARY
' then ctype='[pk]
';
159 else ctype='[unique]
';
161 if first.constraint_name then cols = cats('(
',column_name);
162 else cols=cats(cols,',
',column_name);
164 if last.constraint_name then do;
165 cols=cats(cols,')
',ctype)!!'
167 constraints_used=catx(
' ',constraints_used, constraint_name);
168 call symputx(
'constcheck',1);
171 if last then call symput(
'constraints_used',cats(upcase(constraints_used)));
173 length curds
const col $39;
175 const=constraint_name;
179 proc append base=&pkds data=&syslast;run;
183 data _data_(keep=curds
const col);
184 set &idxinfo (where=(
185 libname=
"%scan(&curds,1,.)"
186 and upcase(memname)=
"%scan(&curds,2,.)"
188 and upcase(indxname) not in (%mf_getquotedstr(&constraints_used))
191 by idxusage indxname;
193 if &constcheck=1 then stop;
194 if _n_=1 and &constcheck=0 then put /
' indexes {';
198 if first.indxname then cols = cats(
'(',name);
199 else cols=cats(cols,
',',name);
201 if last.indxname then
do;
202 cols=cats(cols,
')[unique]')!!
' //'!!indxname;
204 call symputx(
'constcheck',1);
207 length curds
const col $39;
212 proc append base=&pkds data=&syslast;run;
216 if &constcheck =1 then put
' }';
227proc sort data=&pkds nodupkey;
231data &pkds.1 (keep=curds col)
232 &pkds.2 (keep=curds cols);
235 length retconst $39 cols $5000;
236 retain retconst cols;
237 if first.curds then
do;
241 else cols=catx(
' ',cols,upcase(col));
242 if retconst=
const then
do;
244 if last.const then output &pkds.2;
249%
do x=1 %to %sysfunc(countw(&dsnlist,%str( )));
250 %let curds=%scan(&dsnlist,&x,%str( ));
254 set &pkds.2(where=(curds=
"&curds"));
255 call symputx(
'pkcols',cols);
257 %
if &pkcols ne 0 %then %
do;
258 %let curdslist=&curdslist,
"&curds";
263 set &pkds.2(where=(cols=
"&pkcols" and curds not in (&curdslist)));
264 line=
'Ref: "'!!
"&curds"
265 !!cats(
'".(',
"%mf_getquotedstr(&pkcols,dlm=%str(,),quote=%str( ))",
')')
267 !!cats(quote(trim(curds))
269 ,
"%mf_getquotedstr(&pkcols,dlm=%str(,),quote=%str( ))"
278 set &pkds.1(where=(curds=
"&curds"));
282 create table &pkds.5a as
283 select upcase(cats(b.libname,
'.',b.memname)) as curds
286 inner join &colinfo b
287 on a.col=upcase(b.name);
289 create table &pkds.5b as
290 select curds,count(*) as cnt
293 select curds from &pkds.2 where cols="&pkcols"
295 and curds ne "&curds"
297 create table &pkds.6 as
307 colcnt=%sysfunc(countw(&pkcols));
308 if cnt=colcnt then do;
310 line='Ref: "'!!"&curds"
312 !!"%mf_getquotedstr(&pkcols,dlm=%str(,),quote=%str( ))"
314 !!cats(quote(trim(curds))
316 ,"%mf_getquotedstr(&pkcols,dlm=%str(,),quote=%str( ))"
326%if %upcase(&showlog)=YES %then %do;