SQLSTMTパッケージは、DS2プロシジャ内でSQL(FedSQL)を実行したり、その結果を取得したりといった柔軟な処理が出来ます。
SQLSTMTパッケージを使えるようにする
DCL PACKAGE SQLSTMT インスタンス参照名( 'SQL文' );
|
SQLSTMTパッケージを使用するには、パッケージのインスタンスってのを作って、そのインスタンスを参照するための変数(インスタンス参照名)を定義します。
SQL実行
例1
インスタンス参照名.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がどの行にも影響を与えない)
- 例ではプログラムを見やすくするため、リターンコードに対する処理は省略してます。必要に応じ追加下さい。
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]
update DT2 set Y=[B] where X=[A]
SETしたDT1の各オブザベーションの変数A, Bを使って、DT2のデータを更新したいので、
RUNメソッドの中でEXECUTEメソッドを記述しています
(SETでDT1のオブザベーションを読み込む毎に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]);
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]); 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: 基本構文
2: 変数の宣言
3: 変数属性と配列の定義
4: データ型①
8: ユーザー定義パッケージ
0 件のコメント:
コメントを投稿