変数の宣言と代入を見てみましょう。SQL Serverには、OracleのDeclareブロックのような変数宣言専用の領域は用意されていないので、Declare句を使って変数を宣言します。文字列変数Mynameを宣言して、'山田里子'という文字列を代入する例を見てみましょう。
declare MyName VARCHAR2(20); begin MyName := '山田里子'; end;
begin declare @MyName VARCHAR(20); set @MyName = '山田里子'; end
Oracleでは変数の代入は[:=]で結ぶだけですが、SQL ServerではSet句を使っています。また、SQL Serverでは、変数命の頭に必ず[@]をつける必要があります。さらに、文字列の結合を見てみましょう。
set MyName = '山田' + '里子';
Oracleでは[||]で文字列を結合しましたが、SQL Serverでは[+]で結合します。
カーソル処理は、テーブルの中を一行ずつ参照して行うループ処理です。アプリケーションのパフォーマンスアップが要求されるとき、クライアント側のJavaやVBで行っているループ処理をストアドプロシージャのカーソル処理に置き換えることがよくあります。
Oracleのカーソル宣言は、Declareブロックの中でCursor as句を使って宣言します。対してSQL ServerはDECLARE CURSOR文を使います。どちらも中身はSELECT文がそのまま書かれているだけですね。
declare CURSOR 顧客カーソル IS SELECT 顧客コード, 顧客名 FROM 顧客 begin ........ end
begin DECLARE 顧客カーソル CURSOR FOR SELECT 顧客コード, 顧客名 FROM 顧客; .................. end;
カーソルを使ったループ処理は、一行づつFETCHで取り出して、WHILEなどのループ構文に載せるという方法であり、PL/SQLもTransact-SQLもほとんど同じ方法です。使っていくうちに、体で覚えてしまうでしょう。以下に、カーソルを使ったループ処理の例を示します(変数やカーソルの宣言は省略しています)。
OPEN 顧客カーソル ---- カーソルを開く FETCH NEXT FROM 顧客カーソル ---- 一行を取り出して変数に代入する INTO @顧客コード, @顧客名 WHILE @@FETCH_STATUS = 0 ---- 最終行でない限りBEGIN-END間をループ処理する BEGIN PRINT @顧客名 -- 顧客名を出力 FETCH NEXT FROM 顧客カーソル ---- 一行を取り出して変数に代入する INTO @顧客コード, @顧客名 END
途中のWHILE文の条件で、[@@FETCH_STATUS]という関数が使われています。@@で始まるこれらのオブジェクトは、SQL Serverに搭載されているシステム関数と呼ばれるものです。[@@FETCH_STATUS]には、直前のFETCH処理の結果が入ります。ここでは、@@FETCH_STATUS=0の間、つまり、Fetchで取り出す行がある間はループ処理を続けるようになっています。
PL/SQLのエラー処理は、Exceptionブロックというエラー処理専門の領域を利用して行いました。SQL Serverでは、エラー処理専用のExceptionブロックはありませんが、[@@ERROR]というシステム関数に直前の処理のエラー情報が入るので、その値を判断して随時エラー処理をします。
declare ...... begin ...... exception --エラーが起こると以下の処理が実行される when no_data_found; DBMS_OUTPUT.PUT_LINE('データが見つかりませんでした。'); when others; DBMS_OUTPUT.PUT_LINE('システムエラーです。管理者にお問合せください'); end;
UPDATE 顧客 SET 顧客名 = '山田里美' WHERE 顧客コード = '0003' IF @@ERROR = 547 print 'チェック制約に引っかかりました'
エラー処理部が独立したPL/SQLと、処理の流れの中で随時エラー処理を書き込むTransact-SQL。このような構造の違いは優劣で語るものでなく、各製品の個性のようなものでしょう。ただ、細かくError処理をするときには、OracleはBegin-Exception-Endのブロックを多重に囲い込むことになりがちですから、そういう意味では、SQL Serverの方が多少スッキリ見えるかもしれません。
Oracleでは、組み込みパッケージを使って、ストアドプロシージャの返り値として、数値や文字のデータだけでなく、クエリ結果も返すことが出来ます。SQL Serverでは、実にシンプルな方法で同じことが出来ます。その方法とは、「ストアドプログラムの中で最後に実行したSELECT文の結果が呼び元に返る」という単純なもの。JavaやC#といったクライアント側の言語とやりとりするときに便利ですから、覚えておきましょう。
begin SELECT * FROM 顧客; end;
このように、SELECT文を直接書けばOKです。一時テーブルと同時に活用すれば、処理の幅が広がるでしょう。