我想将所有现有数据集从一个库复制到另一个库,但跳过我已经复制的数据集,而不需要指定之前复制的数据集的名称。
上下文如下:我第一次复制库时出现问题,过程中途停止。我正在对许多库进行安全备份,这是一个经常发生的问题。上次发生这种情况时,我在
exclude
语句中指定了所有先前复制的数据集。但是有没有一种方法可以让 SAS 检测输出库中已经存在的数据集并跳过它们再次复制?
我使用的代码:
%macro BACKUP;
%do year=1983 %to 2000;
options compress=yes;
proc copy in=jobs&year. out=backup&year. memtype=data;
*exclude tmp_: data1 companies links education;
run;
%end;
%mend;
%BACKUP;
您可以通过两种方式执行此操作:可以排除 BACKUP 中已存在的数据集,也可以选择 BACKUP 中不存在的数据集。任何一个都会起作用。最好使用包含方法,因为如果相同的数据集已经存在,我们可以防止它不必要地运行 PROC COPY。
我们将使用 SQL 将dictionary.members 合并到其自身上:一个是我们在
jobs
中查看数据集,另一个是我们在 backup
中查看数据集。我们将对其进行子集化,以便我们只有 jobs
中的数据集,而不是使用独占左连接的 backup
中的数据集。
从那里,将每个数据集读入其自己的宏变量中。我们这样做而不是将其读入一个长分隔的宏变量是因为单个宏变量的大小只能是 65,534 个字符。如果有大量数据集,则可能会超出此限制。
我们可以使用 SQL 中的
:var1-
技巧来动态地每行创建顺序宏变量。您也可以使用 DATA 步骤来完成此操作,但 SQL 方式可能更容易理解。
%macro backup;
options compress=yes;
%do year=1983 %to 2000;
proc sql noprint;
select jobs.memname, count(*)
into :dsn1-, :n
from (select memname
from dictionary.members
where libname="JOBS&year" AND memtype='DATA'
) as jobs
LEFT JOIN
(select memname
from dictionary.members
where libname="BACKUP&year" AND memtype='DATA'
) as backup
ON jobs.memname = backup.memname
where missing(backup.memname)
;
quit;
%if(&n > 0) %then %do;
proc copy in=jobs&year. out=backup&year. memtype=data;
select %do i = 1 %to &n;
&&dsn&i
%end;
;
run;
%end;
%else %put NOTE: All datasets in JOBS&year are in BACKUP&year..;
%end;
%mend;
%backup;