Works > 逆引きSQL比較 > SSA > 手続き型言語
SSA
[ SQL ]
[ データベースの情報 ]
[ 手続き型言語 ]
[ その他 ]
■手続き型言語
この項で使用するサンプルテーブルについて ▲TOP
ORACLEとSQL Server系の大きな違いとは? ▲TOP
SQL Server系(Sybase, MS)の経験者が初めてORACLEのストアドプロシージャを作った時に、おそらく面食らうであろうと思われるのが『BEGIN~ENDブロック内にSELECT文が書けない』と言う点です。
例えばTransact-SQLやWatcom-SQLでは、
create procedure sp_hogehoge @inum int as
begin
--何かの処理
--その処理結果に基づき変数やテーブルをSELECTする
select * from ksale where empno = @inum
end
と言った書き方が可能です。上記の sp_hogehoge を Access のパススルークエリーから実行する場合、
exec sp_hogehoge 7
とクエリーのSQLに書いておけば単純にテーブルやビューをSELECTした場合と同様にダイナセットを得る事ができ
ます。
しかし、ORACLE では、BEGIN~ENDブロック(PL/SQLブロック)の中に上記のようなSELECT文を書くことができま
せん。INTOを使用した値の代入、カーソル、サブクエリーにのみ使用できます。
そこでストアドを呼び出して複数行の結果を得るためには、PL/SQL表(配列)を使ったり、カーソルをバインドしたりする必要があります。
これをクライアントアプリケーションから実行するとなると、もうODBCではできないので、ミドルウェアにはネイティブなものを選択する必要があります。
(最近のODBCでは、カーソルについては、
API関数を呼ぶ事で実装できるようです)。
逆にORACLEのみをやっている人は、SQL Server系のストアドを初めて作る時に、自前配列を作ったりしないようにしましょう。
END の直前に SELECT文を書けばよいだけなので。
手続き型言語の書き方は?(BEGIN~ENDブロック) ▲TOP
ORACLE MSSQL SSA MySQL
基本的な制御の例を以下に示します。この文はストアドプログラムとしてコンパイルする必要はありません。
--Watcom-SQLサンプル
begin
--変数宣言
declare mystr varchar(20);
declare mycnt int;
--値の代入
set mycnt = 0;
set mystr = '文字';
--IF文
if mycnt = 0 then
set mystr = '文字2';
message mystr;
else
message '文字3';
end if;
--CASE文
case month(getdate())
when 1 then set mystr = '1月'
when 1 then set mystr = '2月'
when 1 then set mystr = '3月'
when 1 then set mystr = '4月'
else set mystr = '1~4月以外'
end case;
message mystr;
--WHILE-LOOP
while mycnt <= 5 loop
set mycnt = mycnt + 1;
message mycnt;
end loop;
--BEGIN~ENDブロック内でのSELECT文の発行
select now();
end
ストアドプロシージャのサンプル(カーソルを使用するLOOP処理) ▲TOP
ORACLE MSSQL SSA MySQL
カーソルを使用するLOOP処理のサンプルです。
入力パラメータで指定した部署番号に該当する社員について、
役職が『スタッフ』である場合は、氏名の横に『営業スタッフ:』と表示します。
--Watcom-SQLサンプル(カーソルLOOPを使用するストアドプロシージャ)
--drop procedure sp_hoge;
create procedure sp_hoge (in inum int)
begin
--変数宣言
declare err_notfound EXCEPTION FOR SQLSTATE '02000';
declare mystr varchar(50);
--カーソル使用列
declare vempnm varchar(40);
declare vjob varchar(20);
--カーソル宣言
declare mycur cursor for
select empnm,job from kemp where deptno = inum;
--カーソルオープン
open mycur;
--LOOP
looplbl:
loop
--FETCH(行の取り出し)
fetch next mycur into vempnm, vjob;
if sqlstate = err_notfound then
leave looplbl;
end if;
--EOFでなければ何か処理をする
if vjob = 'スタッフ' then
set mystr = '営業スタッフ:';
else
set mystr = '';
end if;
message mystr || vempnm;
end loop looplbl;
--カーソルクローズ
close mycur;
end;
--ストアドプロシージャ実行
exec sp_hoge 1;
ストアドプロシージャのサンプル(アウトパラメータ) ▲TOP
ORACLE MSSQL SSA
プロシージャで更新を行った後、呼出し側に何らかの情報を返したい場合や、返す情報が複数ある場合、
アウトパラメータを使用します。
※因みにファンクションの中では更新をするべきではありません(RDBMSによっては可能だが好ましくない)。
--Watcom-SQLサンプル(OUTパラメータを使用するストアドプロシージャ)
--drop procedure sp_hoge_outp;
create procedure sp_hoge_outp (out ovar varchar(30))
begin
--何やかやの処理
--何やかやの処理終わり
--OUTパラメータにセット
set ovar = 'アウト!';
end;
--ストアドプロシージャ実行
begin
declare myout varchar(30);
call sp_hoge_outp (myout);
select myout;
end;
ストアドプロシージャのサンプル(動的SQL) ▲TOP
ORACLE MSSQL SSA
プロシージャの中で、条件によって使用するテーブルを変えたい場合など、実行するSQLを動的に生成してSQLを実行します。
以下は、区分:1の時は部署番号に該当する社員名を返し、以外の時は区分:1の時は部署番号に該当する部署名を返す例です。
--Watcom-SQLサンプル(動的SQLを使用するストアドプロシージャ)
--EXECUTE IMMEDIATE を使用します
drop procedure sp_hoge_dyna;
create procedure sp_hoge_dyna (in kbn varchar, in inum int)
begin
--変数宣言
declare sqlstmt varchar(200);
--SQL文生成(区分:1の時は部署番号に該当する社員名、以外は部署名)
if kbn = '1' then
set sqlstmt = 'select empnm from kemp where deptno = ' || inum;
else
set sqlstmt = 'select deptnm from kdept where deptno = ' || inum;
end if;
--SQL文実行
execute immediate(sqlstmt);
end;
--ストアドプロシージャ実行(部署番号:1の社員表示)
--※複数行を返すSELECT文はエラーになります。そもそも結果が表示されないので、原則的にDDL(CREATEなど)
-- と更新DML(INSERT,UPDATE,DELETE)にしか使えないのかも?
exec sp_hoge_dyna '1',1;
--ストアドプロシージャ実行(部署番号:1の部署名表示)
exec sp_hoge_dyna '2',1;
ストアドプロシージャのサンプル(一時テーブル) ▲TOP
ORACLE MSSQL SSA
ストアドプロシージャの中で一時的に使用するためのテーブルの使い方。
社員名の一覧をプロシージャ内で一時格納し、クライアント側に返す例です。
--Watcom-SQLサンプル(共有テーブルを使用するストアドプロシージャ)
--一時テーブルと言う概念ではなく、CREATE [ GLOBAL TEMPORARY ] TABLE を使用します。
--あらかじめオブジェクトを作成しておく必要がありますが、セッションをまたいでの競合はありません。
--共有テーブル作成
--drop table tmpkemp;
create GLOBAL TEMPORARY table tmpkemp (empnm varchar(40));
--drop procedure sp_hoge_tmp;
create procedure sp_hoge_tmp ()
begin
--社員マスタから共有テーブルに格納
insert into tmpkemp select empnm from kemp;
--共有テーブルから社員名一覧表示
select empnm from tmpkemp;
end;
--ストアドプロシージャ実行
execute sp_hoge_tmp;
ストアドプロシージャのサンプル(外部コマンド・アプリを実行) ▲TOP
ORACLE MSSQL SSA
ストアドプロシージャから外部のコマンドやアプリケーションを実行します。
--Watcom-SQLサンプル(外部のコマンドやアプリケーションを使用するストアドプロシージャ)
--システムストアドプロシージャxp_cmdshellを使用します。
--※xp_cmdshellは『悪魔のストアド』です。サンプルを見ればわかると思いますが、データベースユーザーが
-- サーバー上でコマンドで実行できる事は『すべて xp_cmdshell から実行可能』です。
-- ですから、セキュリティ面を考慮して使用不可にしているWEBサイトも多いようです。
--drop procedure sp_hoge_cmd;
create procedure sp_hoge_cmd ()
begin
call xp_cmdshell('echo SSA > c:\xpcmd.txt');
call xp_cmdshell('dir c:\*.txt >> c:\xpcmd.txt');
end;
--ストアドプロシージャ実行
execute sp_hoge_cmd;
このページの先頭へ
SSA
[ SQL ]
[ データベースの情報 ]
[ 手続き型言語 ]
[ その他 ]
Works > 逆引きSQL比較 > SSA > 手続き型言語