データベースには、数十万のレコードを含めることができます。 SQL ServerやMySQLなどのデータベース管理システムを介してこれらのレコードを挿入および選択するのは簡単です。ただし、単一のWebページまたはデスクトップアプリケーションに数千のレコードを表示するのは簡単ではありません。スペースとメモリの制約により、大量のレコードを一度に表示することは困難です。
このような問題の一般的な解決策は、ページングを実装することです。 (これはオペレーティングシステムによって実装されるメモリページングではないことに注意してください)プログラミングでのページングとは、一連のページを介してデータを表示することを指します。ランダムなGoogle検索は、何千もの結果をもたらす可能性があります。 Googleはページングを使用してこれらの結果を表示します。検索結果が表示されたGoogleページを下にスクロールすると、次のように表示されます。
ここでは、検索結果が分割されたページ数を確認できます。 [次へ]リンクをクリックすると、他のページが表示されます。
この記事では、OFFSET FETCH NEXT演算子を使用して、フロントエンドアプリケーションにページングを実装する方法を説明します。 OFFSET FETCH NEXT演算子を使用した簡単な例から始めて、ストアドプロシージャを使用して実際に使用する方法を確認します。
SQLServerでのページングにOFFSETFETCHNEXTを使用する
SQL Serverには、ページングを実装するためのOFFSETおよびNEXT演算子が含まれています。 OFFSET演算子は、最初から次のK個の検索結果をオフセットしますが、FETCH NEXT演算子は、KとNが整数であるNEXTN個の結果をフェッチします。
ダミーデータの準備
OFFSET FETCH NEXTの動作を確認する前に、200レコードのダミーデータベースを作成しましょう。適切にバックアップされていることを100%確信している場合は、動作中のデータベースを使用できます。これを行うには、次のスクリプトを実行します。
CREATE Database ShowRoom; GO USE ShowRoom; CREATE TABLE Cars ( id INT PRIMARY KEY IDENTITY, name VARCHAR(50) NOT NULL, company VARCHAR(50) NOT NULL, power INT NOT NULL )
上記のスクリプトでは、Carsという1つのテーブルを持つダミーデータベースShowRoomを作成します。このデータベースにダミーレコードをいくつか追加しましょう。次のスクリプトを実行します。
USE ShowRoom DECLARE @count INT SET @count = 1 DECLARE @carname VARCHAR (50) DECLARE @company_name VARCHAR (50) WHILE (@count <= 200) BEGIN SET @carname = 'Car - ' + LTRIM(@count) SET @company_name = 'Company - '+ LTRIM(@count) INSERT INTO Cars VALUES (@carname, @company_name, @count * 5) SET @count = @count + 1 END
上記のスクリプトを注意深く見てください。上記のスクリプトは、200個のダミーレコードをCarsテーブルに挿入します。スクリプトは、200回の反復でwhileループを使用します。反復ごとに「Car-」という単語が反復番号に追加され、その結果がCarsテーブルの名前列に挿入されます。同様に、「Company-」という単語に反復番号が追加され、各反復で会社の列に挿入されます。最後に、各反復で、反復数に5が掛けられ、結果が累乗列に挿入されます。ここで、Carsテーブルからすべてのレコードを選択すると、結果セットに200レコードが表示されます。これを行うには、次のクエリを実行します。
SELECT * FROM Cars
上記のクエリの部分的な結果のスクリーンショットは次のとおりです。結果には200行が表示されます。
OFFSETFETCHNEXTの例
それでは、OFFSETNEXTの動作を見てみましょう。 OFFSETNEXTの構文は次のとおりです。
SELECT * FROM Table_Name ORDER BY COLUMN_NAME/S OFFSET Number_of_rows_to_Skip ROWS FETCH NEXT Number_of_rows_to_Fetch ROWS ONLY
ここで重要なのは、ORDERBY句をOFFSETFETCHNEXT句とともに使用する必要があるということです。
OFFSET FETCH NEXTの簡単な例を見てみましょう。ここでは、Carsテーブルのid列でデータを並べ替え、最初の20行をスキップして、次の10行をフェッチします。次のスクリプトを実行します。
USE ShowRoom SELECT * FROM Cars ORDER BY id OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY
上記のスクリプトの出力では、最初の20レコードをスキップし、次の10レコードをフェッチしたため、ID値が21〜30のレコードが表示されます。
ストアドプロシージャでのOFFSETFETCHNEXTの使用
Webサイトやデスクトップアプリケーションなどのフロントエンドアプリケーションでページングを実装している場合は、通常、ストアドプロシージャを介してページ番号とページサイズの値をサーバーに送信します。ページ番号とページサイズの値に応じて、ストアドプロシージャは正しい行のセットを返します。ページ番号とページサイズをパラメータとして受け取り、対応するレコードを返すようなストアドプロシージャを作成しましょう。
次のスクリプトを見てください:
USE ShowRoom GO CREATE PROC spGetRecordsByPageAndSize @Page INT, @Size INT AS BEGIN SELECT * FROM Cars ORDER BY id OFFSET (@Page -1) * @Size ROWS FETCH NEXT @Size ROWS ONLY END
上記のスクリプトでは、@Pageと@Sizeの2つのパラメーターを受け取るストアドプロシージャspGetRecordsByPageAndSizeを作成します。ストアドプロシージャは、OFFSET FETCH NEXTを使用して、ページ数とページサイズでレコードをフィルタリングします。たとえば、ページ番号が2で、サイズが20の場合、オフセットは次のようになります。
(2 – 1)* 20 =20
また、FETCH nextの値は、@ Size、つまり20に等しくなります。したがって、IDが21から40のレコードが返されます。上記のスクリプトを実行してストアドプロシージャを作成します。
ストアドプロシージャを作成したら、次のスクリプトを実行して、ページ番号が2、ページサイズが20の場合に返される内容を確認します。
EXECUTE spGetRecordsByPageAndSize 2, 20
上記のスクリプトの出力は次のようになります:
同様に、1ページあたり15レコードの4ページ目のレコードを取得する場合、次のクエリはID46からID60までのレコードを取得します。
EXECUTE spGetRecordsByPageAndSize 4, 15
の出力は次のようになります:
結論
OFFSET FETCH NEXTは、特にページにグループ化された多数のレコードを表示する場合に非常に便利なツールです。この記事では、フロントエンドアプリケーションにページングを実装するためにストアドプロシージャと組み合わせてどのように使用されるかを見ました。