ビューの生成コードを出力するdescribeについて、SQLビューとデータステップビューだと方法が違うから気を付けてって話

さて、以前、SASのビューについて説明したことがありました。

「SASのテーブルビュー(view)について」
http://sas-tumesas.blogspot.jp/2013/12/sasview.html


おさらいとして、

data Q1;
 do X= 1 to 10;
output;
 end;
run;

というデータセットが実体としてあった場合、
Xが偶数のもののみに絞るビューは、以下の2種類の方法で書くことができます。

proc sql noprint;
 create view V1 as
  select *
from Q1
where mod(X,2) = 0;
quit;


data V2/view=V2;
set Q1;
where mod(X,2)=0;
run;











SQLプロシジャのcreate viewか、dataステートメントのviewオプションいずれで
作っても、結果作成される2つのビューの挙動は同じです。

しかし、例えば、contentsプロシジャでビューを見てみると

proc contents data = V1;
run;
proc contents data = V2;
run;

V1の方は





エンジン (ENGINE)           SQLVIEW

とでて、
V2の方は





エンジン (ENGINE)           SASDSV

となって、ビューはビューでも一応種類が違うことがわかります。
要するに、ビューが参照されるときに内部的に実行されるコードが、データステップなのか
SQLなのかってことですね。

この違いについて、ビューのユーザーは基本的に特に何も意識せずともいいのですが、少しだけ
注意があります。

それは、そのビューがどういった定義で生成されたものなのかを確認するとき、
SQLビューに対しては

proc sql;
describe view V1;
quit;

としなければならず、
SASデータセットビューに対しては

data view=V2;
   describe;
run;

としなければならないというルールです。

例えばSQLビューに対して

data view=V1;
   describe;
run;

とすると
ERROR: ビュー WORK.V1 は壊れているか、
       または DATA ステップビューではありません。

と弾かれ、逆にSASデータセットビューに対して
proc sql;
describe view V2;
quit;
とすると
WARNING: WORK.V2 は SQL ビューではありません
と弾かれます。

この、スタンドはスタンドでしか攻撃できないみたいなルールについて
知っていればどうってことないのですが、知らない場合、
特にデータセットビューは知ってるけどSQLビューって何?みたいに片方しか把握してない
メンバーが混在して仕事をする時に、問題になったという体験談を聞いたことがあります。
なんか、てっきり壊れてると思って、他の人が作ったビュー、全部消しちゃったとかがマジであったそうです。
(ビューうんぬんというよりかは、自分が作ってないものを無断であっさり消せちゃう度胸が凄いと思いますが…)

できればビューの作成法は統一した方がいいですし、性質上、1ステっプでの表現力が高いSQLの方が
ビューを作るうえでは優位性があると思ってますが…。

さて、最近メールで「最近あまり更新されませんが、なんかありましたか?心配です」という
heart-warmingなメッセージから「将棋見に行ったりするのにかまけてブログ更新頻度落とすんじゃねぇよ!」
というどちらかというとhurtfulなメッセージまでいただきました。

いや、すみません。
ただ、純粋にネタが枯渇してきたというのが実情なのです。まだSAS歴4~5年程度なので底がそんなに深くないんです。
まあしばらく、色々試したり勉強したりしてネタのストックが溜まるまで、低頻度で気ままに更新させていただきます。(まあ、だいたい、データステップをネタにして、月30-40記事も更新してたっていうのが、ちょっと頭おかしいですよね)


xコマンドで、フォルダ構造のみコピーする話

3/14の電王戦第一局抽選あったたので六本木に見に行ってきます!
このブログ見ていて、もし来られる方がいれば連絡ください!

はい、本題が終わったので、SASの話もちらっと。

Windows環境でコマンドプロンプト使いこなしてると、色々できていいですよね。
僕はさっぱりです。

なんかやりたい時はググってSASのxコマンドにペタッと貼って実行してます。
その中で、ちょっと変わった処理だけど意外と使うな~ってものをご紹介します。

それは、指定したフォルダ内のファイルは無視して、フォルダ構造のみをコピーするというものです。
例えば、ルーチンでやる業務で、前回と同じフォルダが欲しいけど、中に入ってるファイルは別に要らないよというケースです。

一応マクロにしていますが、適当なのでよしなにカスタマイズしてください


/*-----------------------------------------------------------
フォルダ構造のみコピー
※コピー元のフォルダ内のファイルは無視して構造のみをコピー
------------------------------------------------------------*/
%macro folder_emp_copy(basein=,copyout=);
options noxwait noxsync;
%unquote(%bquote(x 'xcopy /t /e "&basein." "&copyout."'));
%mend folder_emp_copy;

/*実行例:デスクトップのTEST1フォルダ内のフォルダ構造をTEST2フォルダ内にコピー*/
%folder_emp_copy(basein=C:\Users\SASYAMA\Desktop\TEST1,
copyout=C:\Users\SASYAMA\Desktop\TEST2)


ついでに、単純に1ファイルをコピーしてリネームするのも

/*--------------------------------------
単一ファイルのリネームコピー
---------------------------------------*/
%macro filecopy(basein=,copyout=);
options noxwait noxsync;
%unquote(%bquote(x 'copy "&basein" "&copyout"'));
%mend filecopy;

/*実行例:AA.txtをBB.txtという名前にリネームしてコピー*/
%filecopy(basein=C:\Users\SASYAMA\Desktop\TEST1\AA.txt,
copyout=C:\Users\SASYAMA\Desktop\TEST2\BB.txt)




エクセルで開いても前ゼロが消えないcsvをods csvで作る話

ods csvのマニアックな話です。

data Q1;
X=1;Y='001';Z='A';output;
X=2;Y='002';Z='B';output;
run;







のような前ゼロがあるデータを考えます。

ods csv file='/folders/myfolders/A1.csv';
proc print data=Q1 noobs;
run;
ods csv close;

として
A1.csvをノートパッド等テキストエディタで開いてみます。










となっています。

同じファイルをEXCEL等のスプレッドシートソフトで開いてみると

のように前ゼロが取れて表示されます。
よく知られた話だと思います。

EXCELで開いても、前ゼロがとれないようにすることできないかな~って考えます。
何のためにか?ただの興味です。

まずはquote_by_typeでクォートしちゃいます。

ods csv file='/folders/myfolders/A2.csv' options(quote_by_type="Yes" );
proc print data=Q1 noobs;
run;
ods csv close;

テキストエディタで開くと

さて、今度はいけるかな~??









はい無理でした~。


最後は、Prepend_Equalsをつけてみます。

ods csv file='/folders/myfolders/A3.csv' options(Prepend_Equals='Yes' quote_by_type="Yes" );
proc print data=Q1 noobs;
run;
ods csv close;

すると、以下のようになんか前に「=」とかつきだしました









今度こそ!!









できた!!わ~い!!


しかし、できたけど、csvって、他のシステムと読み書きでデータの受け渡ししやすいから使うこと
多いわけで、EXCELで確認するときに前ゼロがつく代償に、こんな余計なもんついたcsv作ってもな~。