SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

japan.internet.com翻訳記事

ASP.NETでのデータベース検索ページの作成に役立つ13のヒント

C# 2.0、.NETジェネリック、ストアドプロシージャを組み合わせた手法

ヒント2: セッション変数およびストアドプロシージャパラメータの定義

 表1および表2は、検索ページのセッション変数とストアドプロシージャパラメータをそれぞれ示しています。

表1 ページのセッション変数
変数説明
CurrentFirstRowページングされた結果セットの先頭の行番号
CurrentLastRowページングされた結果セットの末尾の行番号
SortCol現在のソート列
StartRowIndexページングする場合に取得する先頭行
表2 ストアドプロシージャパラメータ
変数説明
FirstNameFirstNameの検索テキスト
LastNameLastNameの検索テキスト
AddressAddressの検索テキスト
CityCityの検索テキスト
StateStateの検索テキスト
ZipZipの検索テキスト
StartRowIndex取得する先頭行
MaxRows取得する最大行数
AlphaCharナビゲート先の英字
SortColソートの基準となる列

 結果セットページには決まった行数しか表示されないため、現在の先頭行インデックスと末尾行インデックスをロジックで保持して、前後のページへのナビゲーションに対処する必要があります。ここで、簡単なシナリオを考えてみましょう。ユーザーが最初に15行の結果セットをもたらすような条件を「City」列で選択したとします。このとき、検索ページに一度に表示できるのは4行だけとします。

1  ANDERSON
2  ARTHUR
3  BARTON
4  BOUTON
5  DEIDRICK
6  DOBSON
7  HAMILTON
8  JERICHO
9  MONTGOMERY
10 RIDDLEY
11 STEVENS
12 TILLY
13 WILCOX
14 WILLIAMS
15 ZEUSS

 最初の実行時、ストアドプロシージャパラメータのStartRowIndexおよびAlphaCharはそれぞれ0と空白であり、ストアドプロシージャは最初の4行を返します。ページの分離コードでは、CurrentFirstRowおよびCurrentLastRowの値を1と4にそれぞれ設定します。

 ユーザーが次のページにナビゲートする場合、分離コードのロジックでは、ストアドプロシージャのStartRowIndexパラメータを5(CurrentLastRow + 1)に設定したうえで、ストアドプロシージャを再び呼び出します。ストアドプロシージャは、「DEIDRICK」~「JERICHO」の行を返し、Webページの分離コードはCurrentFirstRowおよびCurrentLastRowをそれぞれ5と8に設定します。1つ前のページに戻る場合は、分離コードのロジックにより、StartRowインデックスが、セッション変数CurrentFirstRowの値からセッション変数MaxRowsの値を引いた値に設定されます。

 TopボタンとBottomボタンについては、分離コードによって、StartRowIndexを0または-1(ストアドプロシージャは-1を処理します)に設定します。

 最後に、特定の文字(例えば「R」)に直接ジャンプする場合は、ストアドプロシージャのAlphaCharがRに設定され、「RIDDLEY」~「WILCOX」の行が返されます。分離コードにより、セッション変数のCurrentFirstRowおよびCurrentLastRowは、それぞれ10と13に設定されます。

 変数の処理については、いくつか注意すべき点があります。

  • ユーザーが特定の文字(または数字)にジャンプする場合、StartRowIndexパラメータは使用されません。
  • 逆に、ユーザーが通常のナビゲーションボタン(Top、Next、Previous、End)を使用する場合、AlphaCharパラメータは使用されません。

ヒント3: 【重要ポイント】T-SQL 2005の新しいランキング関数

 リスト1は、結果セットを返す完全なストアドプロシージャです(話の結末を先に知りたいタイプの人は、まずリスト1を見てください)。次のコードは、ヒント2のSQLパラメータを使って、SQL Management Studio(図5を参照)で対話的にストアドプロシージャをテストする場合のサンプルのSQLファイルを示しています。

DECLARE @LastName varchar(50),
   @FirstName varchar(50),
   @Address varchar(50),
   @City varchar(50),
   @State varchar(2),
   @Zip  varchar(50),
   @StartRowIndex int,
   @MaxRows int,
   @Alphachar varchar(1) ,
   @SortCol varchar(20)
SET @STATE  = 'NY'
SET @MaxRows = 100
SET @startRowIndex = 0
SET @SortCol  = 'ADDRESS'
SET @AlphaChar  = ''
EXEC [dbo].[LookupEmployees]   @LastName, @FirstName , @Address ,
   @city, @state, @zip, @startRowIndex , @MaxRows ,  @alphachar,
   @SortCol

 この記事の以降の3つのヒントでは、ストアドプロシージャの各部を個別に説明します。

 ヒント2のサンプルデータでは、検索条件(名前や住所など)に一致するレコードごとに、シーケンシャルな行番号が対応していました。今回のストアドプロシージャでは、T-SQL 2005の新しいROW_NUMBER関数を使って、条件に基づいてこの行番号を割り当てます。ROW_NUMBERを使うことで開発者はシーケンシャルなランキング番号を割り当てることができ、ORDER BY文でコーディングする場合と同じようにランキングを並べることができます。

SELECT CustomerID, LastName, FirstName, Address,
   City, State, Zip, ROW_NUMBER() OVER (ORDER BY
CASE  @SortCol
   WHEN 'LASTNAME' THEN LastName+Firstname
   WHEN 'ADDRESS' THEN Address
   WHEN 'CITY' THEN City+LastName+Firstname
   WHEN 'STATE' THEN State+LastName+Firstname
   WHEN 'ZIP'  THEN Zip+LastName+Firstname
   ELSE LastName + Firstname
END)
AS RowNum
FROM Customers

 次のヒントでは、特定のページ/行インデックスの範囲の結果だけを返す、ランキングのフィルタリングについて説明します。

図5 ストアドプロシージャのテスト
図5 ストアドプロシージャのテスト

ヒント4: オプションの検索パラメータおよびページ/行インデックス範囲の処理

 ストアドプロシージャには検索条件用のさまざまなパラメータが含まれていますが、一度に使用するパラメータの数は限られています。例えば、エンドユーザーが検索する情報として考えられるのは名前、住所、または電話番号のみです。ストアドプロシージャは、ユーザーが指定した入力条件についてのみクエリを実行します。開発者によっては、動的SQL文を作成することによってこれを処理します。T-SQLのCOALESCE関数を使用する方法もあります。この関数の場合、NULL入力パラメータのチェックが行われます。

 また、このストアドプロシージャでは、LIKE文を使って部分テキスト検索を実装します。

WHERE LastName LIKE
   '%' + COALESCE(@LastName,LastName)+ '%'  AND
   Address LIKE
   '%' + COALESCE(@Address,Address) + '%' AND ...

 さらに、このストアドプロシージャでは、数値のページングの場合は行の範囲でフィルタを行い、クイックナビゲーションの場合は特定の文字または値で始まる現在のソート列に基づいてフィルタを行う必要があります。ここまでくるとストアドプロシージャがやや複雑になってきます。この処理を実現するには、WHERE句にインラインのCASE文を記述します。

WHERE
CASE WHEN @lPaging = 1 AND @SortCol= 'LASTNAME'
   AND SUBSTRING(LastName,1,1) >=
   RTRIM(@AlphaChar) THEN 1
WHEN @lPaging = 1 AND  @SortCol= 'ADDRESS'
   AND SUBSTRING(Address,1,1) >=
   RTRIM(@AlphaChar) THEN 1
WHEN @lPaging = 0 AND RowNum BETWEEN
   ( CASE @StartRowIndex WHEN -1 THEN
   (RecCount )  -  @MaxRows ELSE
   @StartRowIndex  END )  AND
   (CASE @StartRowIndex WHEN -1 THEN
   ( RecCount ) - @MaxRows ELSE
   @StartRowIndex  END ) + @maxRows
THEN 1

ヒント5: クエリの連携

 ヒント3では、ランキング番号を生成する関数を取り上げました。そして、ヒント4では、2種類のT-SQL WHERE句を取り上げました。1つは最初のクエリに含まれますが、もう1つは、行インデックス範囲または1文字の英数字に基づいて元の結果セットをさらにフィルタするものです。最初の結果セットをさらにフィルタするという概念は、次のヒントへと続きます。

 SQL 2005より前のバージョンでは、中間結果に対してさらにSQL文を記述する場合、開発者は派生テーブル、テーブル変数、一時テーブルなどを使用していました。SQL 2005では、共通テーブル式(CTE)が導入されました。CTEは、基本的には、後に続く1つのステートメントで参照できる動的なビューです。

 CTEは、WITH文で簡単に作成できます。次の例では、CustListTempという名前のCTEを作成しています。

WITH CustListTemp AS
   (SELECT  CustomerID, LastName, FirstName,
    Address, City, State, Zip,
    ROW_NUMBER() OVER (ORDER BY….. )

 このCTEをクエリするコードを作成することができます。CTEを参照できるのは、次に続くSQL文だけです。CTEに対するクエリは、実際にはサブクエリを実行して、行のCOUNTを決定していることに注意してください。ユーザーが最後のMAXROW行数を表示する場合、クエリ内の後のWHERE句では、CTEから条件付きでCOUNTを調べます。

SELECT TOP (@MaxRows)  CustomerID, LastName,
   FirstName, Address, City, State, Zip,
   RowNum  FROM
   (SELECT CustListTemp.*,  (SELECT COUNT(*) from
    CustListTemp) AS RecCount FROM CustListTemp) CustList WHERE...

次のページ
ヒント6: データアクセス層の作成

この記事は参考になりましたか?

japan.internet.com翻訳記事連載記事一覧

もっと読む

この記事の著者

japan.internet.com(ジャパンインターネットコム)

japan.internet.com は、1999年9月にオープンした、日本初のネットビジネス専門ニュースサイト。月間2億以上のページビューを誇る米国 Jupitermedia Corporation (Nasdaq: JUPM) のニュースサイト internet.comEarthWeb.com からの最新記事を日本語に翻訳して掲載するとともに、日本独自のネットビジネス関連記事やレポートを配信。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

Kevin S. Goff(Kevin S. Goff)

.NET、Visual FoxPro、SQL Server、Crystal Reportsによる独自のWebソリューション/デスクトップソリューションを提供するコンサルティンググループ「Common Ground Solutions」の創業者兼主任コンサルタント。ソフトウェアアプリケーションの開発経...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/1444 2007/07/04 14:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー