用于根据日期从数据库/数据仓库中增量抽取数据,和之前提到的检测宏配合起来用,就是完成的数据增量抽取/检验。
数据更新有两种类型:
1、顺序拼接
2、数据更新(历史记录某些字段被刷新)
以下仅举一个顺序拼接的例子:
********************************************************************************************
第一部分:参数设定
1、test.a是本地库待更新的表
2、atime是a表中的格式,为date型
3、database.b是数据库的表
4、btime为b表中格式为时间戳形式。
%let alpha1=test.a;
/*atime 是date格式*/
%let alpha2=atime;
%let alpha3=database.t1;
%let alpha5=t1_s;
/*btime 是datetime格式*/
%let alpha4=btime;
********************************************************************************************
第二部分:调用宏
1、back对现有数据做一些回退,避免少数越界的数据
2、read根据回退的值增量抽取新数据
3、tad对时间戳的时区做转换(已经是东八区的时间就不必要做)
4、对数据库抽取出来的数据做一些个性化的调整,比如选取的变量,重命名等。
5、把数据拼接
%back(&alpha1,&alpha2)
%read(&alpha3,&alpha4)
%tad(&alpha5,&alpha4)
data adjust;
set &alpha5;
&alpha2=datepart(&alpha4);
run;
%append(&alpha1,adjust,&alpha2)
proc delete data=&alpha5 adjust;
run;
********************************************************************************************
以下是宏(dsort是根据主键去重的宏,不再贴出来),6和7在第二种更新方式的时候用。
/*1 回退宏_取现有数据回退一天的时间,结果存入back_last 全局宏变量 */
%macro back(inset,key);
%global back_last;
data aa1;
set &inset;
run;
%dsort(aa1,&key)
data _null_;
if 0 then set aa1 nobs=a;
set aa1;
if _n_=a-1;
call symput('back_last',&key);
run;
proc delete data=aa1;
run;
%mend;
/*2 名字宏_对给定的临时数据加后命名,结果存入nm_app 全局宏变量*/
%macro nm(inset,append);
%global nm_app;
data _null_;
a=substr("&inset",find("&inset",'.')+1);
b=cats(a,"&append");
call symput('nm_app',b);
run;
%mend;
/*3 数据读取宏_从数据仓库截取新数据_依赖于全局宏变量 back_last*/
%macro read(inset,key,itv=2);
data _null_;
a=symget('back_last');
b=(a-&itv)*24*3600;
call symput('new_read',b);
run;
%nm(&inset,_s)
data &nm_app;
set &inset;
where &key gt &new_read;
run;
%mend;
/*4 时间调整宏_格林尼治时间转东八区*/
%macro tad(inset,key);
data &inset;
set &inset;
&key=&key+8*3600;
run;
%mend;
/*5 数据拼接_依赖于全局宏变量back_last*/
%macro append(master,append,key);
data &master;
set &master(where=(&key<=&back_last)) &append(where=(&key > &back_last));
run;
%mend;
/*6 更新宏*/
%macro update(inset,up,key);
%sort(&inset,&key)
%sort(&up,&key)
data &inset;
update &inset &up;
by &key;
%mend;
/*7 对是否有重复主键检查,若有错误则写入临时日志*/
%macro duperr(inset,key);
proc sql;
create table dupaa1 as
select &key,count(*) as cnt from &inset
group by &key
having cnt > 1;
quit;
%if %sysfunc(exist(dupaa1)) %then %do;
data err;
retain setname;
set dupaa1(keep=&key);
if _n_=1;
errtype='DUP';
setname=symget('inset');
run;
%if %sysfunc(exist(err)) %then %do;
data errlog;
set err errlog;
run;
%end;
%end;
%mend;