diff --git a/.gitignore b/.gitignore index 3c3629e..28f1ba7 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ node_modules +.DS_Store \ No newline at end of file diff --git a/base/mp_getddl.sas b/base/mp_getddl.sas index b9425b4..ce3dca6 100644 --- a/base/mp_getddl.sas +++ b/base/mp_getddl.sas @@ -13,9 +13,11 @@ label x='blah'; run; proc sql; describe table &syslast; - %mp_getddl(work,test,flavour=tsql,showlog=YES) +

Dependencies

+ @li mp_getconstraints.sas + @param lib libref of the library to create DDL for. Should be assigned. @param ds dataset to create ddl for @param fref= the fileref to which to write the DDL. If not preassigned, will @@ -26,11 +28,9 @@ ,else libref) @param applydttm= for non SAS DDL, choose if columns are created with native datetime2 format or regular decimal type - @version 9.3 @author Allan Bowe @source https://github.com/sasjs/core - **/ %macro mp_getddl(libref,ds,fref=getddl,flavour=SAS,showlog=NO,schema= @@ -54,16 +54,6 @@ create table _data_ as ; %local tabinfo; %let tabinfo=&syslast; -create table _data_ as - select * from dictionary.indexes - where upcase(libname)="%upcase(&libref)" - %if %length(&ds)>0 %then %do; - and upcase(memname)="%upcase(&ds)" - %end; - order by idxusage, indxname, indxpos - ; -%local idxinfo; %let idxinfo=&syslast; - create table _data_ as select * from dictionary.columns where upcase(libname)="%upcase(&libref)" @@ -72,10 +62,39 @@ create table _data_ as %end; ; %local colinfo; %let colinfo=&syslast; + %local dsnlist; -select distinct upcase(memname) into: dsnlist + select distinct upcase(memname) into: dsnlist separated by ' ' - from &syslast; + from &syslast +; +quit; + +/* Extract all Primary Key and Unique data constraints */ +%mp_getconstraints(lib=%upcase(&libref),ds=%upcase(&ds),outds=_data_) +%local colconst; %let colconst=&syslast; + +%macro addConst(); + data _null_; + length ctype $11; + set &colconst (where=(table_name="&curds" and constraint_type in ('PRIMARY','UNIQUE'))) end=last; + file &fref mod; + by constraint_type constraint_name; + if upcase(strip(constraint_type)) = 'PRIMARY' then ctype='PRIMARY KEY'; + else ctype=strip(constraint_type); + %if &flavour=TSQL %then %do; + column_name=catt('[',column_name,']'); + constraint_name=catt('[',constraint_name,']'); + %end; + if first.constraint_name then do; + put " ,CONSTRAINT " constraint_name ctype "(" ; + put ' ' column_name; + end; + else put ' ,' column_name; + if last.constraint_name then put " )"; + run; +%mend; + data _null_; file &fref; put "/* DDL generated by &sysuserid on %sysfunc(datetime(),datetime19.) */"; @@ -84,13 +103,14 @@ run; %local x curds; %if &flavour=SAS %then %do; data _null_; - file &fref; + file &fref mod; put "proc sql;"; run; %do x=1 %to %sysfunc(countw(&dsnlist)); %let curds=%scan(&dsnlist,&x); data _null_; file &fref mod; + if _n_ eq 1 then put "/* SAS Flavour DDL for %upcase(&libref).&curds */"; length nm lab $1024; set &colinfo (where=(upcase(memname)="&curds")) end=last; @@ -109,22 +129,14 @@ run; lab=" label="!!quote(trim(label)); if notnull='yes' then notnul=' not null'; put name type len fmt notnul lab; - if last then put ');'; run; + /* Extra step for data constraints */ + %addConst() + data _null_; - length ds $128; - set &idxinfo (where=(memname="&curds")) end=last; file &fref mod; - by idxusage indxname; - if unique='yes' then uniq=' unique'; - ds=cats(libname,'.',memname); - if first.indxname then do; - put 'create ' uniq ' index ' indxname; - put ' on ' ds '(' name @@; - end; - else put ',' name @@; - if last.indxname then put ');'; + put ');'; run; /* ods output IntegrityConstraints=ic; @@ -146,7 +158,7 @@ run; %let curds=%scan(&dsnlist,&x); data _null_; file &fref mod; - put "/* DDL for &schema..&curds */"; + put "/* TSQL Flavour DDL for &schema..&curds */"; data _null_; file &fref mod; set &colinfo (where=(upcase(memname)="&curds")) end=last; @@ -169,31 +181,12 @@ run; else if length le 8000 then fmt='[varchar]('!!cats(length)!!')'; else fmt=cats('[varchar](max)'); if notnull='yes' then notnul=' NOT NULL'; - put name fmt notnul; - run; - data _null_; - length ds $128; - set &idxinfo (where=(memname="&curds")); - file &fref mod; - by idxusage indxname; - if unique='yes' then uniq=' unique'; - ds=cats(libname,'.',memname); - if first.indxname then do; - if unique='yes' and nomiss='yes' then do; - put ' ,constraint [' indxname '] PRIMARY KEY'; - end; - else if unique='yes' then do; - /* add nonclustered in case of multiple unique indexes */ - put ' ,index [' indxname '] UNIQUE NONCLUSTERED'; - end; - put ' ('; - put ' [' name ']'; - end; - else put ' ,[' name ']'; - if last.indxname then do; - put ' )'; - end; + put "[" name +(-1) "]" fmt notnul; run; + + /* Extra step for data constraints */ + %addConst() + data _null_; file &fref mod; put ')'; @@ -255,32 +248,15 @@ run; if notnull='yes' then notnul=' NOT NULL'; put name fmt notnul; run; - data _null_; - length ds $128; - set &idxinfo (where=(memname="&curds")); - file &fref mod; - by idxusage indxname; - if unique='yes' then uniq=' unique'; - ds=cats(libname,'.',memname); - if first.indxname then do; - if unique='yes' and nomiss='yes' then do; - put ' ,PRIMARY KEY '; - end; - else if unique='yes' then do; - /* add nonclustered in case of multiple unique indexes */ - put ' ,UNIQUE '; - end; - put ' (' name ; - end; - else put ' ,' name ; - if last.indxname then do; - put ' )'; - end; - run; + + /* Extra step for data constraints */ + %addConst() + data _null_; file &fref mod; put ');'; run; + %end; %end; %if &showlog=YES %then %do; @@ -292,4 +268,4 @@ run; run; %end; -%mend; +%mend; \ No newline at end of file