- - PR -
データベースからある範囲のデータを取り出す方法について
投稿者 | 投稿内容 | ||||||||
---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2004-02-17 19:52
永井和彦さん、返答ありがとうございます。
(一文字違いで自分の先輩の名前なのでドキッとしてしまったw)
うわ、よく考えたらそうでした。。。ユーザー要求とは関係なくTOP句に指定する数値は動的になりますね。ボケてます。。。(悲 # 最初の書き込みを参照した後、打合せになってしまっため返答が遅れましたが、 # エレガントさうんぬんの話は興味のある話ではあり、 # 文字列結合も致し方ないと思うのですが、保守性の面において問題ありと # 認識している部分があるからです。まあ、この話は置いておきましょう。 | ||||||||
|
投稿日時: 2004-02-17 19:53
ROWNUMが振られるのはORDER BYよりも前なので、ソートした結果ではないのです。そのためにインラインビューを使うのですが、それが「裏技」なんですね。。。 「全体のn%を返す」というのはあるんですけどね。。。 | ||||||||
|
投稿日時: 2004-02-17 21:39
きくちゃんさん、返答ありがとうございます。 ユーザー定義関数については使用したことがなかったのと、「文字列結合を使用せずにTOP句に指定する数値を可変にしたい、またはそれに類する構文の書き方があれば知りたい」という要求に対する直接的な回答ではないような気がしましたので、自分なりにユーザー定義関数について調べていました。 しかしながら、こうすればできる!というような解にたどり着くことが出来ませんでした。 (こうやってもできなかったという以前に、こうすればもしかしてという考えにもたどり着けませんでした、とほほ) 申し訳ありませんが、具体的な方法等を示していただけると助かります。 (そこまで甘えるのもなんなんですが・・・) | ||||||||
|
投稿日時: 2004-02-18 02:59
noderaさん、こんばんは。
以下は、与えられたパラメータを抽出条件としてクエリを実行し、その結果セットを取得する単純なテーブル値関数のサンプルです。
この関数の実行結果から先頭の10行を取得する場合、 SELECT TOP 10 FIELD1, FIELD2 FROM MY_FUNCTION(10) というようなSQLを発行しますが、この程度のSQLなら文字列操作で組み立てても、「コンパイル済みクエリの利点を活かしつつ、なおかつ TOP n も動的に指定したい」という要求は満たせるのではないかと思います。 また、戻りや関数内で使用するTABLE型の変数を宣言する際、ID列の指定も可能(だったはず)ですので、ORACLEのROWNUMのような使い方も出来ると思います。 | ||||||||
|
投稿日時: 2004-02-18 11:20
きくちゃんさん、返答ありがとうございます。
きくちゃんさん、Jittaさんの回答を再度検討し、そして結果を得ることに成功しました。 以下のサンプルで目的とするページを抽出できました。 ---------------------------------------------------- ユーザー定義関数を使用して目的とするページのデータを取得する方法 ---------------------------------------------------- ストアドプロシージャ側 CREATE PROCEDURE SP_HOGEHOGE @pageLine int, -- 1ページあたりの行数 @page int -- 抽出対象ページ as -- 抽出開始行の計算 declare @startLine int set @startLine = (@pageLine * (@page - 1)) + 1 -- 抽出終了行の計算 declare @endLine int set @endLine = @startLine + @pageLine - 1 select HOGE_CODE1, HOGE_CODE2, HOGE_NAME from UserFunc() where rownum between @startLine and @endLine ---------------------------------------------------- ユーザー関数側 CREATE FUNCTION UserFunc() RETURNS @Result TABLE(rownum int NOT NULL IDENTITY (1, 1), HOGE_CODE1 int, HOGE_CODE2 int, HOGE_NAME varchar(64)) AS BEGIN insert into @Result (HOGE_CODE1, HOGE_CODE2, HOGE_NAME) select HOGE_CODE1, HOGE_CODE2, HOGE_NAME from HOGEHOGE_TABLE order by HOGE_CODE2, HOGE_CODE1 -- テストのためあえてソートはCODE2、CODE1の順番 return END ---------------------------------------------------- いやあ、なんだか喉のつかえが取れた気分ですよ! これならTOP句も必要ないですね。 永井さんの返答にもちょこっと書きましたが、文字列結合でSQLを組み立てているとデバッグするのがかなり大変だということが分かります。自分の作ったものならまだしも、人の作ったものの不具合修正で、文字列結合だらけのSQLを面倒みなければならなくなった日には、あいたたたた。 まだユーザー定義関数自体についてと、ユーザー定義関数の中でInsertしている部分はパフォーマンスにどのくらい影響度があるのか等、調査は引き続き必要ですが、なにはともあれひとつの結果にたどり着くことができて、非常に勉強になりました。 返答してくださった皆さん、ありがとうございました。 | ||||||||
|
投稿日時: 2004-02-18 15:27
確かに痛いです。また、私の方は現在Oracle、将来MSDEなので、2つの間でSQL文が違うのがなんとも。単純なSELECT以外はストアドプロシージャやビューを作って、コード中ではシンプルなSQLのみ記述するほうがいいなぁ、と、今痛感しています。痛い痛い。。。 |