英文:
How to write a stand-alone script to remove indexes from archived datasets in SAS?
问题
我想创建一个独立的SAS脚本,它可以循环遍历存档磁盘上的所有文件夹,并移除每个数据集的索引。如果需要的话,我可以让脚本在某些文件夹或数据集上省略索引的移除。
我尝试过使用宏来编写脚本,但没有成功。
英文:
I want to create a stand-alone SAS-script which loops through all folders on archive disk and removes the indexes of each dataset. If needed I can have the script omit index removing on certain folders or datasets.
I have tried writing the script using macros but id didn't work
答案1
得分: 1
只需使用 PROC DATASETS 的 INDEX DELETE 语句即可。您可以使用 DICTIONARY.INDEXES 视图查找具有索引的成员名称以生成代码。让我们举个例子。首先,让我们创建一个带有一些索引的数据集。
data class (index=(age sex both=(age sex)));
set sashelp.class;
run;
现在获取库中具有索引的所有数据集的列表。
proc sql;
create table indexes as
select distinct
libname
,nliteral(memname) as memname length=51
from dictionary.indexes
where libname='WORK'
order by 1,2
;
quit;
现在使用该列表生成 PROC DATASETS 代码并使用 %INCLUDE 运行它。
filename code temp;
data _null_;
file code;
set indexes;
by libname memname ;
if first.libname then put 'proc datasets nolist lib=' libname ';' ;
put ' modify ' memname ';'
/ ' index delete _all_;'
/ ' run;';
;
if last.libname then put 'quit;';
run;
%include code / source2;
结果:
520 %include code / source2;
NOTE: %INCLUDE (level 1) file CODE is (system-specific pathname).
521 +proc datasets nolist lib=WORK ;
522 + modify CLASS ;
523 + index delete _all_;
NOTE: All indexes defined on WORK.CLASS.DATA have been deleted.
524 + run;
NOTE: MODIFY was successful for WORK.CLASS.DATA.
525 +quit;
NOTE: PROCEDURE DATASETS used (Total process time):
real time 0.01 seconds
cpu time 0.01 seconds
要针对单个目录执行此操作,只需创建一个指向该目录的 libref,并将 'WORK' 替换为您的 libref 的名称。
要对许多目录执行此操作,您可以为每个目录创建一个单独的 libref,并修改从 DICTIONARY.INDEXES 读取的步骤以选择您定义的所有 librefs。代码生成步骤无需更改,因为它是由具有索引成员列表的数据集的内容驱动的。
英文:
Seems simple enough. Just use the INDEX DELETE statement of PROC DATASETS.
You can use the DICTIONARY.INDEXES view to find the member names that have indexes to drive the code generation.
Let's make an example. First let's make a dataset with some indexes.
data class (index=(age sex both=(age sex)));
set sashelp.class;
run;
Now get the list of all of the dataset in the library that have indexes.
proc sql;
create table indexes as
select distinct
libname
,nliteral(memname) as memname length=51
from dictionary.indexes
where libname='WORK'
order by 1,2
;
quit;
Now use that list to generate PROC DATASETS code and use %INCLUDE to run it.
filename code temp;
data _null_;
file code;
set indexes;
by libname memname ;
if first.libname then put 'proc datasets nolist lib=' libname ';' ;
put ' modify ' memname ';'
/ ' index delete _all_;'
/ ' run;'
;
if last.libname then put 'quit;' ;
run;
%include code / source2;
Results:
520 %include code / source2;
NOTE: %INCLUDE (level 1) file CODE is (system-specific pathname).
521 +proc datasets nolist lib=WORK ;
522 + modify CLASS ;
523 + index delete _all_;
NOTE: All indexes defined on WORK.CLASS.DATA have been deleted.
524 + run;
NOTE: MODIFY was successful for WORK.CLASS.DATA.
525 +quit;
NOTE: PROCEDURE DATASETS used (Total process time):
real time 0.01 seconds
cpu time 0.01 seconds
To do it for a single directory just make a libref pointing to that directory and replace 'WORK' with the name of your libref.
To do it for a LOT of directories you could make a separated libref for each one and the modify the step that reads from DICTIONARY.INDEXES to select ALL of the librefs you have defined.
The code generation step does not need to change as it is driven by the contents of the dataset with the list of members with indexes.
答案2
得分: 0
关于模式(schema)中具有外键的情况,以下示例演示了如何使用元信息 DICTIONARY.REFERENTIAL_CONSTRAINTS
和 DICTIONARY.INDEXES
来从库中的所有数据集中删除所有索引。
proc sql;
create table work.one ( one_id num primary key);
create table work.two ( two_id num primary key
, one_id num references work.one
);
quit;
data ones;
do one_id = 1 to 10 ;
output;
end;
run;
data twos;
do two_id = 1 to 100;
one_id = rand('integer',1,10);
output;
end;
run;
proc append base=one data=ones;
proc append base=two data=twos;
run;
* 获取外键的名称和它们所属的数据集;
proc sql;
create table fks as
select *
from dictionary.referential_constraints
where libname = 'WORK'
order by memname
;
* 首先移除所有外键;
data _null_;
if _n_ = 1 then
call execute ('proc datasets nolist;');
do until (last.memname);
set fks;
where libname = 'WORK' ; * 额外的健壮性保证;
by memname;
if first.memname then
call execute ('modify ' || trim(memname) || '; ic delete ');
call execute (trim(constraint_name));
end;
call execute (';run;');
run;
quit;
* 获取数据集上的索引名称;
proc sql;
create table idxs as
select *
from dictionary.indexes
where libname = 'WORK'
order by memname
;
* 从带有索引的数据集中删除所有索引;
data _null_;
if _n_ = 1 then
call execute ('proc datasets nolist;');
do until (last.memname);
set idxs;
where libname = 'WORK' ; * 额外的健壮性保证;
by memname;
if first.memname then
call execute ('modify ' || trim(memname) || '; ic delete _all_;');
end;
run;
quit;
请注意,以上是给定的代码的翻译部分。
英文:
For the case of the schema, embodied in a library, having foreign keys, the following example demonstrates the use of meta information DICTIONARY.REFERENTIAL_CONSTRAINTS
and DICTIONARY.INDEXES
in removing all indices from all data sets in the library.
proc sql;
create table work.one ( one_id num primary key);
create table work.two ( two_id num primary key
, one_id num references work.one
);
quit;
data ones;
do one_id = 1 to 10 ;
output;
end;
run;
data twos;
do two_id = 1 to 100;
one_id = rand('integer',1,10);
output;
end;
run;
proc append base=one data=ones;
proc append base=two data=twos;
run;
* obtain names of foreign keys and data set they belong to;
proc sql;
create table fks as
select *
from dictionary.referential_constraints
where libname = 'WORK'
order by memname
;
* remove all foreign keys first;
data _null_;
if _n_ = 1 then
call execute ('proc datasets nolist;');
do until (last.memname);
set fks;
where libname = 'WORK' ; * extra robust surety;
by memname;
if first.memname then
call execute ('modify ' || trim(memname) || '; ic delete ');
call execute (trim(constraint_name));
end;
call execute (';run;');
run;
quit;
* obtain names of indices on data sets;
proc sql;
create table idxs as
select *
from dictionary.indexes
where libname = 'WORK'
order by memname
;
* remove all indices from indexed data sets;
data _null_;
if _n_ = 1 then
call execute ('proc datasets nolist;');
do until (last.memname);
set idxs;
where libname = 'WORK' ; * extra robust surety;
by memname;
if first.memname then
call execute ('modify ' || trim(memname) || '; ic delete _all_;');
end;
run;
quit;
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论