Mr.Tです、こんにちは。
そういや、この手の内容は、何度でも挙げてOKだなと思った。
ネタ元:http://kevin_s_goff.typepad.com/kevin_s_goff_weblog/2008/02/2252008-paging.html
あ、Kevin GoffさんのBlogの翻訳ではありません。ネタだけを吸い取って勝手に「ストアド推進」をしているだけです。
自前でページングをしようと思うと、最低この二つがあれば可能になる。
1)表示開始位置Index
2)1ページ内の表示行数
重要になるキーワードは、ROW_NUMBER() OVER (order by ~)
簡単に言えばOrder Byでならべた結果に対して、順位番号をふってくれる便利なもの。
MSDN:http://msdn2.microsoft.com/ja-jp/library/ms186734.aspx
#参考として、http://msdn2.microsoft.com/ja-jp/library/ms189798.aspxあたりも。
こんな感じで使う。
SELECT 社員ID, 苗字, 名前,住所, 電話番号
, ROW_NUMBER() OVER (ORDER BY
社員ID,
苗字,
名前,
住所,
電話番号) as 順位
from 社員テーブル
で、たいていの場合、この結果をCTEを使って、ページング用の出力のためのSQLに組み込む。
さて、ここで、開始位置Indexと、表示行数の仕様を簡単にきめておこう。
開始位置Indexは、パラメータ「@開始位置」、表示行数は、パラメータ「@表示行数」としよう。
- 開始位置Indexは、 0以上の正の整数。開発言語などで色々な範囲が設定できると思うが、
とりあえず、無難なところでIntegerとか使ってみる。アプリケーション側ではなんでもいい。
- 開始位置Indexは、順位0の場合は、指定されていないことにする。つまり、先頭からとってくることを意味する。
そのため、論理的には1以上の値が入らないとページめくりはできない。
- 表示行数は、1以上の正の整数。それ以外の値がはいってきたら、デフォルトで100とする。
適当なので、こんなもので。
with 社員ワーク as (
SELECT 社員ID, 苗字, 名前,住所, 電話番号
, ROW_NUMBER() OVER (ORDER BY
社員ID,
苗字,
名前,
住所,
電話番号) as 順位
from 社員テーブル
)
SELECT 社員ID, 苗字, 名前,住所, 電話番号
FROM 社員ワーク
WHERE
順位 BETWEEN
(CASE
WHEN @開始位置=0
THEN 1
ELSE @開始位置
END )
AND
( CASE
WHEN @表示行数<1
THEN 0
ELSE @開始位置
END)
+ (CASE
WHEN @表示行数<1 THEN 100
ELSE @表示行数)
CASEの使い方は、非常に利用度が高いので、覚えておくとストアドを書くのが楽になると思う。思いたい。
たとえば、開始Indexでなくとも、ページ番号のようなものを使おうとおもったら、ページ内行数から、開始位置を計算して
似たような処理をかけばいい。これで、自前のページング処理が、かけるようになるじゃないか。
こんなものから派生すれば、ページング用のこんなの↓、
こんなページ用の番号でさえも、ストアドから出すこともできるだろう。つまり、データソースにできるということだから、
バインディングしてやれば、あっという間にオリジナルの処理がつくれるようになる。
アプリ側で、がりがりページングの処理を書かなくてもいいのは、楽じゃないかな、と思ったりしてます。