2016年4月1日金曜日

DS2プロシジャ入門9:SQLSTMTパッケージ



SQLSTMTパッケージは、DS2プロシジャ内でSQL(FedSQL)を実行したり、その結果を取得したりといった柔軟な処理が出来ます。




構文① SQLの実行


SQLSTMTパッケージを使えるようにする
 DCL PACKAGE SQLSTMT  インスタンス参照名( 'SQL文' );

SQLSTMTパッケージを使用するには、パッケージのインスタンスってのを作って、そのインスタンスを参照するための変数(インスタンス参照名)を定義します。


SQL実行
 インスタンス参照名.EXECUTE();


例1
* サンプルデータ ;
data DT1;
input A B;
cards;
1 100
2 200
;

data DT2;
input X Y;
cards;
1 .
1 .
2 .
2 .
;

* SQLSTMTを使ってデータの更新を行う ;
proc ds2;
   data _NULL_ ;
     dcl package sqlstmt sq( 'update DT2 set Y=1 where X=1' );
     method init();
          sq.execute();
     end;
   enddata;
   run;
quit;

dcl package sqlstmt sq( 'update DT2 set Y=1 where X=1' );
データ更新するSQL文を定義して、、

sq.execute();
実行しています。


📝ポイントと注意点
  • SQL文は「PROC SQL」ではなく「FedSQLステートメント」である点に注意(FedSQLの詳細についてはSAS社のリファレンスを参照下さい)
  • FedSQLステートメントはシングルクオーテーションで囲む
  • EXECUTEメソッドは以下のリターンコードを返します
    • 0 = 実行が成功、1 = エラーがある、2 = データがない(UPDATEやDELETEがどの行にも影響を与えない)
  • 例ではプログラムを見やすくするため、リターンコードに対する処理は省略してます。必要に応じ追加下さい。



例2
proc ds2;
   data _NULL_ ;
     dcl package sqlstmt sq( 'update DT2 set Y=? where X=?' , [B A);
     method run();
          set DT1;
          sq.execute();
     end;
   enddata;
   run;
quit;

dcl package sqlstmt sq( 'update DT2 set Y=? where X=?' , [B A] );
SETしたDT1の変数[B A]をSQL文中の「?」に渡すよう指定してます。

update DT2 set Y=[B] where X=[A]

SETしたDT1の各オブザベーションの変数A, Bを使って、DT2のデータを更新したいので、
RUNメソッドの中でEXECUTEメソッドを記述しています
(SETでDT1のオブザベーションを読み込む毎にSQLを実行している)



構文② SQLの結果を取得する


SQLの結果をDS2プロシジャ内の変数に紐づける
 インスタンス参照名.BINDRESULTS( [変数1 変数2 ・・・] );

「SQLの結果に含まれる変数」と「BINDRESULTSに指定した変数」を、左から順に紐づけます
(同じ変数名同士で紐づけるわけではないので注意)


SQLの結果から1行取ってきて、紐づけた変数にセットする
 インスタンス参照名.FETCH();


例1
proc ds2;
   data OUT1 / overwrite=yes ;
     dcl double A2 B2;
     dcl package sqlstmt sq( 'select A,B from DT1' );
     method init();
          sq.execute();
          sq.bindresults([A2 B2]);

          do while (sq.fetch()=0);
              output;
          end;
     end;
   enddata;
   run;
quit;

dcl package sqlstmt sq('select A,B from DT1');
sq.execute();
SQLでselectしたA,Bを、

sq.bindresults([A2 B2]);
DS2プロシジャ内で定義した変数A2, B2に紐づけます。

do while (sq.fetch()=0);
   output;
end;
SQLの結果を1行ずつ取り出して、紐づけた変数A2,B2に格納します。


📝ポイントと注意点
  • BINDRESULTSメソッドは以下のリターンコードを返します
    • 0 = 実行が成功、1 = エラーがある
  • FETCHメソッドは実行される度にSQLの結果から次の行を読み込んでいき、以下のリターンコードを返します
    • 0 = 実行が成功、1 = エラーがある、2 = データがない(FETCHする行がこれ以上ない)
  • 例ではリターンコードに対する処理は省略してます。必要に応じ追加下さい。



例2
proc ds2;
   data _NULL_ ;
     dcl double A2 B2;
     dcl package sqlstmt sq1( 'select A,B from DT1' );
     dcl package sqlstmt sq2( 'update DT2 set Y=? where X=?',[B2 A2] );
     method init();
          sq1.execute();
          sq1.bindresults([A2 B2]);

          do while (sq1.fetch()=0);
              sq2.execute();
          end;
     end;
   enddata;
   run;
quit;

今回の集大成。

dcl package sqlstmt sq1('select A,B from DT1');
sq1.bindresults([A2 B2]);
SQLでselectしたA,Bを、DS2プロシジャ内で定義した変数A2,B2に紐づけて取り出しながら、その値を使って、、

dcl package sqlstmt sq2('update DT2 set Y=? where X=?',[B2 A2]);
別のデータに更新をかけようというわけです。



DS2プロシジャ入門記事

1: 基本構文
: 変数の宣言
3: 変数属性と配列の定義
4: データ型①
8: ユーザー定義パッケージ
9: SQLSTMTパッケージ


0 件のコメント:

コメントを投稿