Большое количество таблиц измерений, каждая из которых имеет большое количество столбцов атрибутов, - это большая вещь для изучения.Для общего решения вам потребуется использовать информацию метаданных для получения списка наборов данных в библиотеке, проверить эти наборы данных на наличие признаков «scd2-idness» (например, столбец идентификатора, названный аналогично имени набора данных),Для каждой таблицы scd2 вы снова посещаете метаданные, чтобы получить столбцы не-scd (любой столбец, который не является идентификатором записи, идентификатором измерения или допустимым диапазоном дат).Затем будет записан процесс, проходящий через набор данных и идентифицирующий случаи, когда значение атрибута изменилось или не изменилось по сравнению с предыдущим допустимым диапазоном дат.
Рассмотрим некоторые сгенерированные данные scd-2 с произвольным именем измерения,имеющие произвольные имена атрибутов (то есть столбцов).Некоторые из столбцов в группе вынуждены быть «статичными» (это могут быть те столбцы, которые могут рассматриваться как опущенные в вашем вопросе)
%macro random_name(len=8);
%local i result;
%do i = 1 %to &len;
%let result = &result.%sysfunc(byte(%sysfunc(ranuni(123))*26+65));
%end;
&result
%mend;
%macro make_data(lib=WORK, N=40);
%local outcount i j p suffix out;
%do outcount = 1 %to &N;
%let out = dimtable_%random_name();
%let idvar = &out._id;
%local top cCount nCount cName nName namelen name;
%let top = %sysevalf ( 1000 * %sysfunc(ranuni(123)), FLOOR);
%let nCount = %sysevalf ( 20 * %sysfunc(ranuni(123)), FLOOR);
%let cCount = %sysevalf ( 20 * %sysfunc(ranuni(123)), FLOOR);
%do i = 1 %to &nCount;
%let namelen = %sysevalf(16 * %sysfunc(ranuni(123)), CEIL);
%let name = ;
%do j = 1 %to &namelen;
%let name = &name.%sysfunc(byte(%sysfunc(ranuni(123))*26+65));
%end;
%local numvar&i;
%let numvar&i = nattr&i._&name.;
%end;
%do i = 1 %to &cCount;
%let namelen = %sysevalf(16 * %sysfunc(ranuni(123)), CEIL);
%let name = ;
%do j = 1 %to &namelen;
%let name = &name.%sysfunc(byte(%sysfunc(ranuni(123))*26+65));
%end;
%local chrvar&i;
%let chrvar&i = cattr&i._&name.;
%end;
data &out;
do rowid = 1 to ⊤
if rowid = 1 or ranuni(123) > 0.8 then do;
&idvar + 1;
valid_from_dt = 0;
valid_to_dt = '01-jan-1970'd + floor(60 * ranuni(123));
format valid: yymmdd10.;
attrib
%if &nCount %then %do; %do i = 1 %to &nCount; &&numvar&i %end; length=8 format=6. %end;
%if &cCount %then %do; %do i = 1 %to &cCount; &&chrvar&i %end; length=$20 %end;
;
%if &nCount %then %do; array num %do i = 1 %to &nCount; &&numvar&i %end; ; %end;
%if &cCount %then %do; array chr %do i = 1 %to &cCount; &&chrvar&i %end; ; %end;
array staticN[0:&nCount] _temporary_;
array staticC[0:&cCount] _temporary_;
do _n_ = 1 to hbound(staticN); staticN(_n_) = ranuni(123) < 0.40; end;
do _n_ = 1 to hbound(staticC); staticC(_n_) = ranuni(123) < 0.40; end;
do _n_ = 1 to dim(num);
num(_n_) = CEIL (1000 * ranuni(123));
end;
do _n_ = 1 to dim(chr);
chr(_n_) = repeat(byte(65+26*ranuni(123)), 15 * ranuni(123));
end;
end;
valid_from_dt = valid_to_dt + 1;
valid_to_dt = valid_from_dt + ceil(60 * ranuni(123));
do _n_ = 1 to dim(num);
if not staticN(_n_) then num(_n_) = CEIL (1000 * ranuni(123));
end;
do _n_ = 1 to dim(chr);
if not staticC(_n_) then chr(_n_) = repeat(byte(65+26*ranuni(123)), 15 * ranuni(123));
end;
output;
end;
run;
%end;
%mend;
options mprint;
%let SCD2_LIB = WORK;
proc datasets nolist noprint lib=&SCD2_LIB mt=data kill;
run;
quit;
%make_data(lib=&SCD2_LIB, n=1)
Общий макрос экзаменационного scd-2 записывается на выходтаблица, которая содержит пропущенные значения (пробелы), когда значение атрибута не изменилось по сравнению с предыдущим допустимым диапазоном дат.Он не совсем «отбрасывается», но является хорошим визуальным средством для просмотра «пробелов», которые означают неизменную информацию.
Макрос вызывается другим процессом, который обнаруживает таблицы scd-2 и определяет числовые и символьные переменные, которые будутбыть рассмотрены как атрибуты, которые могут иметь изменения значения.Вывод сохраняется в соответствующем наборе данных с именем * _changed.
%macro scan_scd(data=, idvar=, nvars=, cvars=);
%local i nCount cCount;
%let nCount = %sysfunc(countw(&nvars));
%let cCount = %sysfunc(countw(&cvars));
%do i = 1 %to &nCount; %local nvar&i; %let nvar&i = %scan(&nvars,&i); %end;
%do i = 1 %to &cCount; %local cvar&i; %let cvar&i = %scan(&cvars,&i); %end;
data &data._changes;
if 0 then set &data(keep=rowid &idvar valid_from_dt valid_to_dt);
retain
%do i = 1 %to &nCount; &&nvar&i &&nvar&i.._was %end;
%do i = 1 %to &cCount; &&cvar&i &&cvar&i.._was %end;
;
set
&data (obs=0 rename=(
%do i = 1 %to &nCount; &&nvar&i = ___nprv&i %end;
%do i = 1 %to &cCount; &&cvar&i = ___cprv&i %end;
))
&data (obs=0 rename=(
%do i = 1 %to &nCount; &&nvar&i = &&nvar&i.._was %end;
%do i = 1 %to &cCount; &&cvar&i = &&cvar&i.._was %end;
))
&data;
by &idvar.;
if first.&idvar. then do;
%do i = 1 %to &nCount; ___nprv&i = &&nvar&i; %end;
%do i = 1 %to &nCount; &&nvar&i.._was = .; %end;
%do i = 1 %to &cCount; ___cprv&i = &&cvar&i; %end;
%do i = 1 %to &cCount; &&cvar&i.._was = ''; %end;
end;
else do;
%do i = 1 %to &nCount; &&nvar&i.._was = ifn (&&nvar&i = ___nprv&i, ., ___nprv&i); %end;
%do i = 1 %to &cCount; &&cvar&i.._was = ifc (&&cvar&i = ___cprv&i,'', ___cprv&i); %end;
%do i = 1 %to &nCount; ___nprv&i = &&nvar&i; %end;
%do i = 1 %to &cCount; ___cprv&i = &&cvar&i; %end;
end;
run;
%mend;
scd-2, обнаружение и вызов сканирования
Имена всех таблиц в некоторой библиотеке-кандидате
proc sql;
create table scd_datasets as select libname, memname from dictionary.tables
where libname = "&SCD2_LIB"
;
quit;
имя файла mprint и опция mfile могут сохранять сгенерированный макрос во внешнем файле для более детального изучения и изучения;
filename mprint "c:\temp\macro-source.sas" ;
%let rc = %sysfunc(fdelete(%sysfunc(pathname(mprint))));
options nomprint;
options mprint mfile;
Обрабатывать каждый набор данных.Используйте функции набора данных для доступа к информации метаданных набора данных.
data _null_;
set scd_datasets;
scd_table = catx('.',libname,memname);
scd_id_var = trim(memname) || '_ID';
rowid_var = 'ROWID';
from_dt_var = 'VALID_FROM_DT';
to_dt_var = 'VALID_TO_DT';
dsid = open (scd_table);
if dsid then do;
if varnum(dsid, scd_id_var)
& varnum(dsid, rowid_var)
& varnum(dsid, from_dt_var)
& varnum(dsid, to_dt_var)
then do;
length nvars $32000;
length cvars $32000;
nvars = '';
cvars = '';
do _n_ = 1 to attrn(dsid,'nvar');
varname = upcase(varname(dsid,_n_));
vartype = vartype(dsid,_n_);
if varname ne upcase(scd_id_var)
& varname ne rowid_var
& varname ne from_dt_var
& varname ne to_dt_var
then do;
if vartype = 'N' then nvars=catx(' ',nvars,varname);
if vartype = 'C' then cvars=catx(' ',cvars,varname);
end;
end;
%* Queue the invocation of the SCD-2 scanner macro for this particular data set;
call execute (
%* '%put NOTE: ' ||;
'%nrstr(%scan_scd(' ||
'data=' || trim(scd_table) ||
', idvar=' || scd_id_var ||
', nvars=' || trim(nvars) ||
', cvars=' || trim(cvars) ||
'))'
);
end;
dsid = close(dsid);
end;
run;
options nomfile nomprint;
filename mprint;