トップページへ PASSJ ブログへ
トップページへ
分科会
特集!
コミュニケーション
資格
セミナー・コンファレンス
インフォメーション
開発者必見! 覚えておきたいSQL Serverの便利機能
文=株式会社システムインテグレータ 堀 真人
第7回
Transact-SQLをマスターしよう!
Oracleではご存知のように、ストアドプロシージャやストアドファンクションを書くときにSQLを拡張したPL/SQLという言語を使います。SQL Serverでも同様に、SQLを拡張したTransact-SQLという言語を使います。PL/SQLで書ける処理は、Transact-SQLでもひと通りできるようになっています。

具体的には、変数の使用、カーソルを使った処理、ループ処理、エラー処理などが用意されています。サーバーに翻訳済みのプログラムを置くことで高速化を図るストアドプロシージャという概念は、SQL規格にも取り込まれているので、各RDBMSも足並みがそろってきました。PL/SQLを扱える人であれば、 Transact-SQLもすぐに覚えられるでしょう
Tips 1

変数の宣言と代入


変数の宣言と代入を見てみましょう。SQL Serverには、OracleのDeclareブロックのような変数宣言専用の領域は用意されていないので、Declare句を使って変数を宣言します。文字列変数Mynameを宣言して、'山田里子'という文字列を代入する例を見てみましょう。

Oracle

declare
  MyName VARCHAR2(20);
begin
  MyName := '山田里子';
end;

SQL Server

begin
  declare @MyName VARCHAR(20);
  set @MyName = '山田里子';

end

Oracleでは変数の代入は[:=]で結ぶだけですが、SQL ServerではSet句を使っています。また、SQL Serverでは、変数命の頭に必ず[@]をつける必要があります。さらに、文字列の結合を見てみましょう。

SQL Server

  set MyName = '山田' + '里子';

Oracleでは[||]で文字列を結合しましたが、SQL Serverでは[+]で結合します。



Tips 2

カーソルとループ処理


カーソル処理は、テーブルの中を一行ずつ参照して行うループ処理です。アプリケーションのパフォーマンスアップが要求されるとき、クライアント側のJavaやVBで行っているループ処理をストアドプロシージャのカーソル処理に置き換えることがよくあります。

Oracleのカーソル宣言は、Declareブロックの中でCursor as句を使って宣言します。対してSQL ServerはDECLARE CURSOR文を使います。どちらも中身はSELECT文がそのまま書かれているだけですね。

Oracle

declare
  CURSOR 顧客カーソル IS
  SELECT 顧客コード, 顧客名 FROM 顧客
begin
  ........
end

SQL Server

begin
  DECLARE 顧客カーソル CURSOR FOR
  SELECT 顧客コード, 顧客名
  FROM 顧客;

  ..................
end;

カーソルを使ったループ処理は、一行づつFETCHで取り出して、WHILEなどのループ構文に載せるという方法であり、PL/SQLもTransact-SQLもほとんど同じ方法です。使っていくうちに、体で覚えてしまうでしょう。以下に、カーソルを使ったループ処理の例を示します(変数やカーソルの宣言は省略しています)。

SQL Server

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で取り出す行がある間はループ処理を続けるようになっています。



Tips 3

エラー処理の方法


PL/SQLのエラー処理は、Exceptionブロックというエラー処理専門の領域を利用して行いました。SQL Serverでは、エラー処理専用のExceptionブロックはありませんが、[@@ERROR]というシステム関数に直前の処理のエラー情報が入るので、その値を判断して随時エラー処理をします。

Oracle

declare
  ......
begin
  ......
exception --エラーが起こると以下の処理が実行される
  when no_data_found;
    DBMS_OUTPUT.PUT_LINE('データが見つかりませんでした。');
  when others;
    DBMS_OUTPUT.PUT_LINE('システムエラーです。管理者にお問合せください');
end;

SQL Server

UPDATE 顧客 SET 顧客名 = '山田里美'
WHERE 顧客コード = '0003'

IF @@ERROR = 547
  print 'チェック制約に引っかかりました'

エラー処理部が独立したPL/SQLと、処理の流れの中で随時エラー処理を書き込むTransact-SQL。このような構造の違いは優劣で語るものでなく、各製品の個性のようなものでしょう。ただ、細かくError処理をするときには、OracleはBegin-Exception-Endのブロックを多重に囲い込むことになりがちですから、そういう意味では、SQL Serverの方が多少スッキリ見えるかもしれません。



Tips 3

Transact-SQLはクエリ結果を返すことができる


Oracleでは、組み込みパッケージを使って、ストアドプロシージャの返り値として、数値や文字のデータだけでなく、クエリ結果も返すことが出来ます。SQL Serverでは、実にシンプルな方法で同じことが出来ます。その方法とは、「ストアドプログラムの中で最後に実行したSELECT文の結果が呼び元に返る」という単純なもの。JavaやC#といったクライアント側の言語とやりとりするときに便利ですから、覚えておきましょう。

SQL Server

begin
  SELECT * FROM 顧客;
end;

このように、SELECT文を直接書けばOKです。一時テーブルと同時に活用すれば、処理の幅が広がるでしょう。




・ 第1回 SQL クエリアナライザのクエリ実行機能
・ 第2回 SQL クエリアナライザ Part 2
・ 第3回 開発者のための、日常的バックアップの小ワザ
・ 第4回 SQL Server 転ばぬ先の杖!
・ 第5回 エラーをやっつけろ!
・ 第6回 SQL構文の違いを押さえる!
・ 第7回 Transact-SQLをマスターしよう!
・ 第8回 パフォーマンス監視ノウハウ


著者プロフィール
株式会社システムインテグレータ
堀 真人(HORI, Masato)

http://www.sint.co.jp/

新横浜で2年半Oracleを使い、埼玉に飛んでからはSQLServerと戦う毎日を送る“DBバイリンガル”な27歳。
ITとは、「アイデアを支えるテクノロジー」と心得る。
趣味はレゲエとSQL Server。愛読書はレゲエ専門誌「Riddim」とデータベース専門誌「DBマガジン」。

← 特集!DBバイリンガル 目次

PASSJメールニュース 著作権ついて プライバシーポリシー リンクポリシー お問い合わせ
(C) 2005 Professional Association for SQL Server Japan. All rights reserved.