BREAKING CHANGE: Introduction of 4 new tables for capturing information related to catalogs and their objects. Migration script prepared and available in the DB folder (usual place)
337 lines
8.0 KiB
SAS
337 lines
8.0 KiB
SAS
/**
|
|
@file mpe_refreshtables.sas
|
|
@brief Refreshes the data catalog
|
|
@details Assumes library is already assigned.
|
|
Usage:
|
|
|
|
%mpe_refreshtables(sashelp)
|
|
|
|
<h4> SAS Macros </h4>
|
|
@li bitemporal_dataloader.sas
|
|
@li mf_existfeature.sas
|
|
@li mf_getengine.sas
|
|
@li mf_getschema.sas
|
|
@li mp_getconstraints.sas
|
|
|
|
@version 9.3
|
|
@author 4GL Apps Ltd
|
|
**/
|
|
|
|
%macro mpe_refreshtables(lib,ds=#all);
|
|
%let lib=%upcase(&lib);
|
|
%let ds=%upcase(&ds);
|
|
%local engine; %let engine=%mf_getengine(&lib);
|
|
%local schema; %let schema=%mf_getschema(&lib);
|
|
%put running &sysmacroname &lib(&engine &schema) for &ds;
|
|
proc sql;
|
|
create table cols as
|
|
select libname as libref
|
|
,upcase(memname) as dsn
|
|
,memtype
|
|
,upcase(name) as name
|
|
,type
|
|
,length
|
|
,varnum
|
|
,label
|
|
,format
|
|
,idxusage
|
|
,notnull
|
|
from dictionary.columns
|
|
where upcase(libname)="&lib"
|
|
%if &ds ne #ALL %then %do;
|
|
and upcase(memname)="&ds"
|
|
%end;
|
|
;
|
|
|
|
%mp_abort(iftrue= (&syscc ne 0)
|
|
,mac=&_program
|
|
,msg=%str(syscc=&syscc afer &lib cols extraction)
|
|
)
|
|
|
|
%if &engine=SQLSVR %then %do;
|
|
proc sql;
|
|
connect using &lib;
|
|
create table work.indexes as
|
|
select * from connection to &lib(
|
|
select
|
|
s.name as SchemaName,
|
|
t.name as memname,
|
|
tc.name as name,
|
|
ic.key_ordinal as KeyOrderNr
|
|
from
|
|
sys.schemas s
|
|
inner join sys.tables t on s.schema_id=t.schema_id
|
|
inner join sys.indexes i on t.object_id=i.object_id
|
|
inner join sys.index_columns ic on i.object_id=ic.object_id
|
|
and i.index_id=ic.index_id
|
|
inner join sys.columns tc on ic.object_id=tc.object_id
|
|
and ic.column_id=tc.column_id
|
|
where i.is_primary_key=1
|
|
and s.name=%str(%')&schema%str(%')
|
|
order by t.name, ic.key_ordinal ;
|
|
);disconnect from &lib;
|
|
create table finalcols as
|
|
select a.*
|
|
,case when b.name is not null then 1 else 0 end as pk_ind
|
|
from work.cols a
|
|
left join work.indexes b
|
|
on a.dsn=b.memname
|
|
and upcase(a.name)=upcase(b.name)
|
|
order by libref,dsn;
|
|
%end;
|
|
%else %do;
|
|
%local dsn;
|
|
%if &ds = #ALL %then %let dsn=;
|
|
|
|
%mp_getconstraints(lib=&lib.,ds=&dsn,outds=work.constraints)
|
|
|
|
|
|
/* extract cols that are clearly primary keys */
|
|
proc sql;
|
|
create table work.pk4sure as
|
|
select libref
|
|
,table_name
|
|
,constraint_name
|
|
,constraint_order
|
|
,column_name as name
|
|
from work.constraints
|
|
where constraint_type='PRIMARY'
|
|
order by 1,2,3,4;
|
|
|
|
/* extract unique constraints where every col is also NOT NULL */
|
|
proc sql;
|
|
create table work.sum as
|
|
select a.libref
|
|
,a.table_name
|
|
,a.constraint_name
|
|
,count(a.column_name) as unq_cnt
|
|
,count(b.column_name) as nul_cnt
|
|
from work.constraints(where=(constraint_type ='UNIQUE')) a
|
|
left join work.constraints(where=(constraint_type ='NOT NULL')) b
|
|
on a.libref=b.libref
|
|
and a.table_name=b.table_name
|
|
and a.column_name=b.column_name
|
|
group by 1,2,3
|
|
having unq_cnt=nul_cnt;
|
|
|
|
|
|
/* extract cols from the relevant unique constraints */
|
|
create table work.pkdefault as
|
|
select a.libref
|
|
,a.table_name
|
|
,a.constraint_name
|
|
,b.constraint_order
|
|
,b.column_name as name
|
|
from work.sum a
|
|
left join work.constraints(where=(constraint_type ='UNIQUE')) b
|
|
on a.libref=b.libref
|
|
and a.table_name=b.table_name
|
|
and a.constraint_name=b.constraint_name
|
|
order by 1,2,3,4;
|
|
|
|
/* extract cols from the relevant unique INDEXES */
|
|
create table work.pkfromindex as
|
|
select libname as libref
|
|
,memname as table_name
|
|
,indxname as constraint_name
|
|
,indxpos as constraint_order
|
|
,name
|
|
from dictionary.indexes
|
|
where nomiss='yes' and unique='yes' and upcase(libname)="&lib"
|
|
%if &ds ne #ALL %then %do;
|
|
and upcase(memname)="&ds"
|
|
%end;
|
|
order by 1,2,3,4;
|
|
|
|
/* create one table */
|
|
data work.finalpks;
|
|
set pkdefault pk4sure pkfromindex;
|
|
pk_ind=1;
|
|
/* if there are multiple unique constraints, take the first */
|
|
by libref table_name constraint_name;
|
|
retain keepme;
|
|
if first.table_name then keepme=1;
|
|
if first.constraint_name and not first.table_name then keepme=0;
|
|
if keepme=1;
|
|
run;
|
|
|
|
/* join back to starting table */
|
|
proc sql;
|
|
create table finalcols as
|
|
select a.*
|
|
,b.constraint_order
|
|
,case when b.pk_ind=1 then 1 else 0 end as pk_ind
|
|
from work.cols a
|
|
left join work.finalpks b
|
|
on a.libref=b.libref
|
|
and a.dsn=b.table_name
|
|
and upcase(a.name)=upcase(b.name)
|
|
order by libref,dsn,constraint_order;
|
|
|
|
%end;
|
|
|
|
%mp_abort(iftrue= (&syscc ne 0)
|
|
,mac=&_program
|
|
,msg=%str(syscc=&syscc afer &lib indexes extraction)
|
|
)
|
|
|
|
/* load columns */
|
|
%bitemporal_dataloader(base_lib=&mpelib
|
|
,base_dsn=mpe_datacatalog_vars
|
|
,append_dsn=finalcols
|
|
,PK=LIBREF DSN NAME
|
|
,etlsource=&sysmacroname
|
|
,loadtype=TXTEMPORAL
|
|
,tech_from=TX_FROM
|
|
,tech_to=TX_TO
|
|
%if &ds ne #ALL %then %do;
|
|
,close_vars=LIBREF DSN
|
|
%end;
|
|
,dclib=&mpelib
|
|
)
|
|
|
|
/* prepare tables */
|
|
proc sql;
|
|
create table work.tabs as select
|
|
libname as libref
|
|
,upcase(memname) as dsn
|
|
,memtype
|
|
%if %mf_existfeature(DBMS_MEMTYPE)=1 %then %do;
|
|
,dbms_memtype
|
|
%end;
|
|
%else %do;
|
|
,'n/a' as dbms_memtype format=$32.
|
|
%end;
|
|
,typemem
|
|
,memlabel
|
|
,nvar
|
|
,compress
|
|
from dictionary.tables
|
|
where upcase(libname)="&lib"
|
|
%if &ds ne #ALL %then %do;
|
|
and upcase(memname)="&ds"
|
|
%end;
|
|
;
|
|
data tabs2;
|
|
set finalcols;
|
|
length pk_fields $512;
|
|
retain pk_fields;
|
|
by libref dsn;
|
|
if first.dsn then pk_fields='';
|
|
if pk_ind=1 then pk_fields=catx(' ',pk_fields,name);
|
|
if last.dsn then output;
|
|
run;
|
|
|
|
proc sql;
|
|
create table work.finaltabs as
|
|
select a.libref
|
|
,a.dsn
|
|
,a.memtype
|
|
,a.dbms_memtype
|
|
,a.typemem
|
|
,a.memlabel
|
|
,a.nvar
|
|
,a.compress
|
|
,b.pk_fields
|
|
from work.tabs a
|
|
left join work.tabs2 b
|
|
on a.libref=b.libref
|
|
and a.dsn=b.dsn;
|
|
|
|
%bitemporal_dataloader(base_lib=&mpelib
|
|
,base_dsn=mpe_datacatalog_tabs
|
|
,append_dsn=finaltabs
|
|
,PK=LIBREF DSN
|
|
,etlsource=&sysmacroname
|
|
,loadtype=TXTEMPORAL
|
|
,tech_from=TX_FROM
|
|
,tech_to=TX_TO
|
|
,dclib=&mpelib
|
|
%if &ds ne #ALL %then %do;
|
|
,close_vars=LIBREF
|
|
%end;
|
|
)
|
|
|
|
/* prepare table frequently changing attributes */
|
|
proc sql;
|
|
%if &engine=SQLSVR %then %do;
|
|
connect using &lib;
|
|
create table work.attrs as select * from connection to &lib(
|
|
SELECT SCHEMA_NAME(schema_id) as 'schema', name, create_date, modify_date
|
|
FROM sys.tables ;
|
|
);
|
|
create table work.nobs as select * from connection to &lib(
|
|
SELECT SCHEMA_NAME(A.schema_id) AS 'schema'
|
|
,A.Name, AVG(B.rows) AS 'RowCount'
|
|
FROM sys.objects A
|
|
INNER JOIN sys.partitions B ON A.object_id = B.object_id
|
|
WHERE A.type = 'U'
|
|
GROUP BY A.schema_id, A.Name
|
|
);
|
|
disconnect from &lib;
|
|
create table statustabs as select
|
|
a.libref
|
|
,a.dsn
|
|
,b.create_date as crdate
|
|
,b.modify_date as modate
|
|
,. as filesize
|
|
,c.RowCount as nobs
|
|
from work.tabs a
|
|
left join work.attrs(where=(schema="&schema")) b
|
|
on upcase(a.dsn)=upcase(b.name)
|
|
left join work.nobs(where=(schema="&schema")) c
|
|
on upcase(a.dsn)=upcase(c.name);
|
|
%end;
|
|
%else %do;
|
|
create table statustabs as select
|
|
libname as libref
|
|
,upcase(memname) as dsn
|
|
,crdate
|
|
,modate
|
|
,filesize
|
|
,nobs
|
|
from dictionary.tables
|
|
where upcase(libname)="&lib"
|
|
%if &ds ne #ALL %then %do;
|
|
and upcase(memname)="&ds"
|
|
%end;
|
|
;
|
|
%end;
|
|
|
|
%bitemporal_dataloader(base_lib=&mpelib
|
|
,base_dsn=mpe_datastatus_tabs
|
|
,append_dsn=statustabs
|
|
,PK=LIBREF DSN
|
|
,etlsource=&sysmacroname
|
|
,loadtype=TXTEMPORAL
|
|
,tech_from=TX_FROM
|
|
,tech_to=TX_TO
|
|
,dclib=&mpelib
|
|
%if &ds ne #ALL %then %do;
|
|
,close_vars=LIBREF
|
|
%end;
|
|
)
|
|
|
|
%if &ds = #ALL %then %do;
|
|
proc sql;
|
|
create table statuslibs as select
|
|
libref
|
|
,sum(filesize) as libsize
|
|
,count(*) as table_cnt
|
|
from statustabs
|
|
group by 1;
|
|
|
|
%bitemporal_dataloader(base_lib=&mpelib
|
|
,base_dsn=mpe_datastatus_libs
|
|
,append_dsn=statuslibs
|
|
,PK=LIBREF
|
|
,etlsource=&sysmacroname
|
|
,loadtype=TXTEMPORAL
|
|
,tech_from=TX_FROM
|
|
,tech_to=TX_TO
|
|
,dclib=&mpelib
|
|
)
|
|
%end;
|
|
|
|
%mend mpe_refreshtables;
|