describe tableの出力をコピーしてcreate tableして中身はinsert文にして、人にコードを渡す場合に必要なデータセットもその中で作るコードにしたいといった処理

投稿タイトルの意味がわかりませんよね。すみません

例えば、データベースからデータをひっぱってきて、それに対するプログラムを書いたとします。
それを他の場所にいる人に渡すとき、その人の場所からはデータベースにアクセスできないとします。
そうなると、実行しながらコードレビューしてもらうためには、当然データセットもつけなければいけないわけです。でもほんとにちょっとしたデータセットだといちいち添付するのも面倒だし、コードの中で作らしちゃえと思う時ありますよね。

input+cardsで作ればいいんですが、僕嫌いなんです。だからいつも

data DS;
x=1;y=2;output;
x=3;y=4;output;
run;

みたいな書き方で作ります。筋のいいコードではないです。

ただ、データセットにフォーマットやらラベルやら長さが細かく設定されていると
それの通りにデータセットを作成するのは面倒ですよね。proc contentsしてアウトプットから
定義情報コピペでもいいのですが、

僕が一番いいと思うやり方を紹介します。ただし、この方法の評判はめっぽう悪く、
余計面倒だと言われたこともあるので、これがいいと思えるのは僕だけの可能性があります。

なので読んでいて、こいつ何してんだと思われたら流してください。

今WORKに
データセット名[BASE]という下記のデータがあって





これを同じものをコードで作成したいとします。

まず
proc sql;
 describe table BASE;
quit;

と実行します。

するとログに













とこんな風にでます。
SQLのdescribe tableはCONTENTSプロシジャのSQL版みたいな感じで
そのデータセットの定義情報を教えてくれます。
しかもいいのが、そのデータセットをそのまま作成できるコードの形式で教えてくれるところです。

ようするに、上のログの create table ~ );までをコピーして
SQLプロシジャの中につっこんで実行すれば、そのままBASEと同じ定義情報をもったデータセットが作成されるのです。

ただし、このままでは空のデータセットで、中身はありません。
データを作成する部分を作成しなければなりません。

まず、

proc datasets nolist;
 modify BASE;
  attrib _all_ format= ;
quit;

で、後の処理でちょっと都合が悪いのでフォーマットを飛ばします。

そして

data _NULL_;
 set BASE;
 put 'values(' X ',"' Y '",' Z ')';

run;

とします。文字型変数に対してはコーテーション包みを忘れないようにします。
上を実行するとログには











こんな感じででます。
このvaluesの部分が欲しいのです。

さて後は、SQLプロシジャの中で
まず最初のdescribe tableででたログをコピペして
バッファサイズはいらないので消して、
その下に insert into BASE と一文打ってから
あとは上のputでだしたvaluesの部分をコピペして、最後にセミコロンでしめれば
はい、データセットを完全に再現するプログラムのできあがり!
(ユーザー定義フォーマットつけている場合は、formatプロシジャを前もって書いてくださいね)

proc sql noprint;
create table WORK.BASE
  (
   X num label='Xのラベル',
   Y char(100) label='Yのラベル',
   Z num format=YYMMDDS10. label='Zのラベル'
  );
 insert into BASE
 values(1 ,"A ",5022 )
 values(2 ,"C ",5122 )
 values(3 ,"D ",6022 )
;
quit;

基本コピペなので超楽に感じるんですけど、やっぱり途中でコチョコチョ、コード足しているんで
めんどうですかね?
じゃあマクロにでもしてください。そんなに難しくないはず




0 件のコメント:

コメントを投稿