1
0
mirror of https://github.com/sasjs/core.git synced 2026-01-15 12:30:06 +00:00

FEAT: adding Primary Key constraints

This commit is contained in:
rafgag
2020-08-03 16:51:14 +02:00
parent 9d9a72220f
commit 45e646565f
2 changed files with 56 additions and 71 deletions

1
.gitignore vendored
View File

@@ -1 +1,2 @@
node_modules node_modules
.DS_Store

View File

@@ -4,18 +4,14 @@
@details Data Definition Language relates to a set of SQL instructions used @details Data Definition Language relates to a set of SQL instructions used
to create tables in SAS or a database. The macro can be used at table or to create tables in SAS or a database. The macro can be used at table or
library level. The default behaviour is to create DDL in SAS format. library level. The default behaviour is to create DDL in SAS format.
Usage: Usage:
data test(index=(pk=(x y)/unique /nomiss)); data test(index=(pk=(x y)/unique /nomiss));
x=1; x=1;
y='blah'; y='blah';
label x='blah'; label x='blah';
run; run;
proc sql; describe table &syslast; proc sql; describe table &syslast;
%mp_getddl(work,test,flavour=tsql,showlog=YES) %mp_getddl(work,test,flavour=tsql,showlog=YES)
@param lib libref of the library to create DDL for. Should be assigned. @param lib libref of the library to create DDL for. Should be assigned.
@param ds dataset to create ddl for @param ds dataset to create ddl for
@param fref= the fileref to which to write the DDL. If not preassigned, will @param fref= the fileref to which to write the DDL. If not preassigned, will
@@ -26,11 +22,9 @@
,else libref) ,else libref)
@param applydttm= for non SAS DDL, choose if columns are created with native @param applydttm= for non SAS DDL, choose if columns are created with native
datetime2 format or regular decimal type datetime2 format or regular decimal type
@version 9.3 @version 9.3
@author Allan Bowe @author Allan Bowe
@source https://github.com/sasjs/core @source https://github.com/sasjs/core
**/ **/
%macro mp_getddl(libref,ds,fref=getddl,flavour=SAS,showlog=NO,schema= %macro mp_getddl(libref,ds,fref=getddl,flavour=SAS,showlog=NO,schema=
@@ -54,16 +48,6 @@ create table _data_ as
; ;
%local tabinfo; %let tabinfo=&syslast; %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 create table _data_ as
select * from dictionary.columns select * from dictionary.columns
where upcase(libname)="%upcase(&libref)" where upcase(libname)="%upcase(&libref)"
@@ -72,10 +56,28 @@ create table _data_ as
%end; %end;
; ;
%local colinfo; %let colinfo=&syslast; %local colinfo; %let colinfo=&syslast;
%local dsnlist; %local dsnlist;
select distinct upcase(memname) into: dsnlist select distinct upcase(memname) into: dsnlist
separated by ' ' 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;
data _data_ (drop=column_name);
set &colconst (where = (constraint_type in ('PRIMARY','UNIQUE')));
by libref table_name constraint_type constraint_name;
length column_list $ 500;
retain column_list;
if first.constraint_name then column_list='';
column_list = catx(', ', column_list, column_name);
if last.constraint_name then output;
run;
%local tabconst; %let tabconst=&syslast;
data _null_; data _null_;
file &fref; file &fref;
put "/* DDL generated by &sysuserid on %sysfunc(datetime(),datetime19.) */"; put "/* DDL generated by &sysuserid on %sysfunc(datetime(),datetime19.) */";
@@ -84,13 +86,14 @@ run;
%local x curds; %local x curds;
%if &flavour=SAS %then %do; %if &flavour=SAS %then %do;
data _null_; data _null_;
file &fref; file &fref mod;
put "proc sql;"; put "proc sql;";
run; run;
%do x=1 %to %sysfunc(countw(&dsnlist)); %do x=1 %to %sysfunc(countw(&dsnlist));
%let curds=%scan(&dsnlist,&x); %let curds=%scan(&dsnlist,&x);
data _null_; data _null_;
file &fref mod; file &fref mod;
if _n_ eq 1 then put "/* SAS Flavour DDL for %upcase(&libref).&curds */";
length nm lab $1024; length nm lab $1024;
set &colinfo (where=(upcase(memname)="&curds")) end=last; set &colinfo (where=(upcase(memname)="&curds")) end=last;
@@ -109,22 +112,23 @@ run;
lab=" label="!!quote(trim(label)); lab=" label="!!quote(trim(label));
if notnull='yes' then notnul=' not null'; if notnull='yes' then notnul=' not null';
put name type len fmt notnul lab; put name type len fmt notnul lab;
if last then put ');'; run;
/* Extra step for data constraints */
data _null_;
set &tabconst (where=(table_name="&curds")) end=last;
length ctype $11;
file &fref mod;
by constraint_type constraint_name;
if upcase(strip(constraint_type)) = 'PRIMARY' then ctype='PRIMARY KEY';
else ctype=strip(constraint_type);
column_list=strip(column_list);
put " ,CONSTRAINT " constraint_name " " ctype "(" column_list ")";
run; run;
data _null_; data _null_;
length ds $128;
set &idxinfo (where=(memname="&curds")) end=last;
file &fref mod; file &fref mod;
by idxusage indxname; put ');';
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 ');';
run; run;
/* /*
ods output IntegrityConstraints=ic; ods output IntegrityConstraints=ic;
@@ -146,7 +150,7 @@ run;
%let curds=%scan(&dsnlist,&x); %let curds=%scan(&dsnlist,&x);
data _null_; data _null_;
file &fref mod; file &fref mod;
put "/* DDL for &schema..&curds */"; put "/* TSQL Flavour DDL for &schema..&curds */";
data _null_; data _null_;
file &fref mod; file &fref mod;
set &colinfo (where=(upcase(memname)="&curds")) end=last; set &colinfo (where=(upcase(memname)="&curds")) end=last;
@@ -172,28 +176,16 @@ run;
put name fmt notnul; put name fmt notnul;
run; run;
data _null_; data _null_;
length ds $128; length ctype $11;
set &idxinfo (where=(memname="&curds")); set &tabconst (where=(table_name="&curds")) end=last;
file &fref mod; file &fref mod;
by idxusage indxname; by constraint_type constraint_name;
if unique='yes' then uniq=' unique'; if upcase(strip(constraint_type)) = 'PRIMARY' then ctype='PRIMARY KEY';
ds=cats(libname,'.',memname); else ctype=strip(constraint_type);
if first.indxname then do; column_list=strip(column_list);
if unique='yes' and nomiss='yes' then do; put " ,CONSTRAINT " constraint_name " " ctype "(" column_list ")";
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;
run; run;
data _null_; data _null_;
file &fref mod; file &fref mod;
put ')'; put ')';
@@ -255,32 +247,24 @@ run;
if notnull='yes' then notnul=' NOT NULL'; if notnull='yes' then notnul=' NOT NULL';
put name fmt notnul; put name fmt notnul;
run; run;
/* Extra step for data constraints */
data _null_; data _null_;
length ds $128; length ctype $11;
set &idxinfo (where=(memname="&curds")); set &tabconst (where=(table_name="&curds")) end=last;
file &fref mod; file &fref mod;
by idxusage indxname; by constraint_type constraint_name;
if unique='yes' then uniq=' unique'; if upcase(strip(constraint_type)) = 'PRIMARY' then ctype='PRIMARY KEY';
ds=cats(libname,'.',memname); else ctype=strip(constraint_type);
if first.indxname then do; column_list=strip(column_list);
if unique='yes' and nomiss='yes' then do; put " ,CONSTRAINT " constraint_name " " ctype "(" column_list ")";
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; run;
data _null_; data _null_;
file &fref mod; file &fref mod;
put ');'; put ');';
run; run;
%end; %end;
%end; %end;
%if &showlog=YES %then %do; %if &showlog=YES %then %do;
@@ -292,4 +276,4 @@ run;
run; run;
%end; %end;
%mend; %mend;