以前、「世代管理機能でデータセットの更新履歴(更新前後のDS)を残す_GENMAX=オプション」
http://sas-tumesas.blogspot.jp/2013/11/dsgenmax.html
で世代データセットを作る話をしました。
世代データセットが作られるようにしておけば、確かにそのデータセットが同名で再作成されるような場合に、世代データセットが作成されるので、更新内容を追うことができますが、例えば
data DS1(genmax=10);
X=1;
run;
data DS1;
modify DS1;
X=2;
run;
のような処理をした場合、DS1の中身のXの値は2になりますが、世代データセットは一切
作成されません。
何故か?modifyステートメントは、元のデータセットを更新するものであり、
一度消して再作成するdata XX;set XX;とは違うからです。
データセットが同名で上書き作成された場合のみ世代データセットの対象になります。
その理屈からsqlプロシジャでupdateをしたときも作成されず、proc appendでデータセットを再作成せずに追加処理した場合も世代データセットは作られません。
では、そういった更新処理に対して、変更内容を確認することはできないのでしょうか?
当然できます。
今、以下の2つのデータセットがあって、Q1について、内容に変更がある度にそれを記録し、後で確認する必要があったとします。
data Q1;
X=1;Y='A';output;
X=2;Y='B';output;
run;
data Q2;
X=3;Y='C';output;
run;
ここでQ1に対して何か処理をする前に、
proc datasets ;
audit Q1;
initiate;
quit;
とします。これによってQ1に対してauditが作成されるようになります。
ただし、世代データセットと違い、ユーザーの目には直接触れない、見えない箇所でSASが勝手に記録をとります。
さて、それでは、一気に以下のコードを実行します。
data Q1;
modify Q1(where=(X=1));
X=9;
Y='Z';
run;
proc append base=Q1 data=Q2;
run;
data Q1;
modify Q1;
where X=2;
remove;
run;
関係のないクイズ、Q1の中身は一体どうなっているでしょうか?
答え
で、ここで、どうやってQ1に対する監査証跡を確認するのかというと、
data A1;
set Q1(type=audit);
run;
として、A1の中身を見てみると
こんなことになってます。
見方を簡単に説明すると
_ATDATETIME_がデータに何かしら操作が加えられた日時です。
_ATOBSNO_は対象となったオブザベーション番号です。
_ATUSERID_は変更を行ったログインユーザー名です。
_ATOPCODE_は操作内容でDRはそのオブザベーションが読み込まれたこと、DWはそのオブザベーションに何かデータが書かれたことDAはオブザベーションの追加、DDは削除です。
以上のことを踏まえてA1を解読してみると
2014年の6月29日の深夜2時20分12秒に、1オブザベーション目が読み込まれ、同時間に
X=9 Y=Zに書き換えられ、そしてその4秒後、3オブザベーション目にデータが追加され、
間髪いれず2オブザベーション目が削除され、全ての処理はSASYAMAというユーザーによって
行われたんだということが丸裸になります。
さらに詳しくはドキュメントを読んでください。
これは、うまく利用すれば凄いことです。これと同じことをするマクロとかを自作しようとしたら
頭抱えちゃいそうです。それがproc datasetsでちょろっと指定するだけでできてしまうので。
とても大事で、変更履歴を残したいものがあるなら、同名での再作成ができないようにしたうえで
AUDITを作るようにしておいて、変更は全てmodify等の更新処理で行えばよいですね。
実践でやったことないですけどね。
でもなんか、これ、本来の用途と違うことに応用できそうな気がしていて、ちょっと面白いことできないか考え中です。