From c6a18a41681e752a137154db9742f8e121dc85e3 Mon Sep 17 00:00:00 2001 From: rafgag <69139928+rafgag@users.noreply.github.com> Date: Wed, 5 Aug 2020 12:42:27 +0200 Subject: [PATCH 1/2] Fix: Unique Indexes Added --- base/mp_getddl.sas | 126 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 95 insertions(+), 31 deletions(-) diff --git a/base/mp_getddl.sas b/base/mp_getddl.sas index 9b18f31..179406c 100644 --- a/base/mp_getddl.sas +++ b/base/mp_getddl.sas @@ -19,7 +19,7 @@ @li mp_getconstraints.sas @param lib libref of the library to create DDL for. Should be assigned. - @param ds dataset to create ddl for (optional) + @param ds dataset to create ddl for @param fref= the fileref to which to write the DDL. If not preassigned, will be assigned to TEMP. @param flavour= The type of DDL to create (default=SAS). Supported=TSQL @@ -68,35 +68,48 @@ create table _data_ as separated by ' ' from &syslast ; -quit; + +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; /* 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; - %else %if &flavour=PGSQL %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; + %global constraints_used; + data _null_; + length ctype $11 constraint_name_orig $256 constraints_used $5000; + set &colconst (where=(table_name="&curds" and constraint_type in ('PRIMARY','UNIQUE'))) end=last; + file &fref mod; + by constraint_type constraint_name; + retain constraints_used; + constraint_name_orig=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; + constraints_used = catx(' ', constraints_used, constraint_name_orig); + put " ,CONSTRAINT " constraint_name ctype "(" ; + put ' ' column_name; + end; + else put ' ,' column_name; + if last.constraint_name then do; + put " )"; + call symput('constraints_used',strip(constraints_used)); + end; + run; + %put &=constraints_used; %mend; data _null_; @@ -108,13 +121,13 @@ run; %if &flavour=SAS %then %do; data _null_; file &fref mod; + put "/* SAS Flavour DDL for %upcase(&libref).&curds */"; 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; @@ -142,6 +155,25 @@ run; file &fref mod; put ');'; run; + + /* Create Unique Indexes, but only if they were not already defined within the Constraints section. */ + data _null_; + *length ds $128; + set &idxinfo (where=(memname="&curds" and unique='yes' and indxname not in (%sysfunc(tranwrd("&constraints_used",%str( ),%str(",")))))); + file &fref mod; + by idxusage indxname; +/* ds=cats(libname,'.',memname); */ + if first.indxname then do; + put 'CREATE UNIQUE INDEX ' indxname "ON &libref..&curds (" ; + put ' ' name ; + end; + else put ' ,' name ; + *else put ' ,' name ; + if last.indxname then do; + put ');'; + end; + run; + /* ods output IntegrityConstraints=ic; proc contents data=testali out2=info; @@ -191,6 +223,24 @@ run; /* Extra step for data constraints */ %addConst() + /* Create Unique Indexes, but only if they were not already defined within the Constraints section. */ + data _null_; + *length ds $128; + set &idxinfo (where=(memname="&curds" and unique='yes' and indxname not in (%sysfunc(tranwrd("&constraints_used",%str( ),%str(",")))))); + file &fref mod; + by idxusage indxname; + *ds=cats(libname,'.',memname); + if first.indxname then do; + /* add nonclustered in case of multiple unique indexes */ + put ' ,index [' indxname +(-1) '] UNIQUE NONCLUSTERED ('; + put ' [' name +(-1) ']'; + end; + else put ' ,[' name +(-1) ']'; + if last.indxname then do; + put ' )'; + end; + run; + data _null_; file &fref mod; put ')'; @@ -222,9 +272,7 @@ run; from dictionary.libnames where libname="&libref" and engine='POSTGRES'; %let schema=%sysfunc(coalescec(&schemaactual,&schema,&libref)); - data _null_; - file &fref mod; - put "CREATE SCHEMA &schema;"; + %do x=1 %to %sysfunc(countw(&dsnlist)); %let curds=%scan(&dsnlist,&x); data _null_; @@ -252,9 +300,7 @@ run; else if type='num' then fmt=' DOUBLE PRECISION'; else fmt='VARCHAR('!!cats(length)!!')'; if notnull='yes' then notnul=' NOT NULL'; - /* quote column names in case they represent reserved words */ - name2=quote(trim(name)); - put name2 fmt notnul; + put name fmt notnul; run; /* Extra step for data constraints */ @@ -265,6 +311,24 @@ run; put ');'; run; + /* Create Unique Indexes, but only if they were not already defined within the Constraints section. */ + data _null_; + *length ds $128; + set &idxinfo (where=(memname="&curds" and unique='yes' and indxname not in (%sysfunc(tranwrd("&constraints_used",%str( ),%str(",")))))); + file &fref mod; + by idxusage indxname; +/* ds=cats(libname,'.',memname); */ + if first.indxname then do; + put 'CREATE UNIQUE INDEX ' indxname "ON &schema..&curds (" ; + put ' ' name ; + end; + else put ' ,' name ; + *else put ' ,' name ; + if last.indxname then do; + put ');'; + end; + run; + %end; %end; %if &showlog=YES %then %do; From 17f03b75074990e6b1be99f9d8ffbbcd5817ef68 Mon Sep 17 00:00:00 2001 From: rafgag <69139928+rafgag@users.noreply.github.com> Date: Wed, 5 Aug 2020 13:48:16 +0200 Subject: [PATCH 2/2] Fix: previous changes restored --- base/mp_getddl.sas | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/base/mp_getddl.sas b/base/mp_getddl.sas index 179406c..578061a 100644 --- a/base/mp_getddl.sas +++ b/base/mp_getddl.sas @@ -19,7 +19,7 @@ @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 ds dataset to create ddl for (optional) @param fref= the fileref to which to write the DDL. If not preassigned, will be assigned to TEMP. @param flavour= The type of DDL to create (default=SAS). Supported=TSQL @@ -98,6 +98,10 @@ create table _data_ as column_name=catt('[',column_name,']'); constraint_name=catt('[',constraint_name,']'); %end; + %else %if &flavour=PGSQL %then %do; + column_name=catt('"',column_name,'"'); + constraint_name=catt('"',constraint_name,'"'); + %end; if first.constraint_name then do; constraints_used = catx(' ', constraints_used, constraint_name_orig); put " ,CONSTRAINT " constraint_name ctype "(" ; @@ -272,7 +276,9 @@ run; from dictionary.libnames where libname="&libref" and engine='POSTGRES'; %let schema=%sysfunc(coalescec(&schemaactual,&schema,&libref)); - + data _null_; + file &fref mod; + put "CREATE SCHEMA &schema;"; %do x=1 %to %sysfunc(countw(&dsnlist)); %let curds=%scan(&dsnlist,&x); data _null_; @@ -300,7 +306,9 @@ run; else if type='num' then fmt=' DOUBLE PRECISION'; else fmt='VARCHAR('!!cats(length)!!')'; if notnull='yes' then notnul=' NOT NULL'; - put name fmt notnul; + /* quote column names in case they represent reserved words */ + name2=quote(trim(name)); + put name2 fmt notnul; run; /* Extra step for data constraints */ @@ -319,10 +327,10 @@ run; by idxusage indxname; /* ds=cats(libname,'.',memname); */ if first.indxname then do; - put 'CREATE UNIQUE INDEX ' indxname "ON &schema..&curds (" ; - put ' ' name ; + put 'CREATE UNIQUE INDEX "' indxname +(-1) '" ' "ON &schema..&curds (" ; + put ' "' name +(-1) '"' ; end; - else put ' ,' name ; + else put ' ,"' name +(-1) '"'; *else put ' ,' name ; if last.indxname then do; put ');';