MYSQL5.1で以下のようなストアドプロシージャを作成したとします。


delimiter //
CREATE PROCEDURE TEST()
BEGIN
SELECT HTL.TEST1, HTL.TEST2 FROM
(
SELECT TEST1, TEST2
FROM TESTA
WHERE ID = 4
UNION ALL
SELECT TEST3, TEST4
FROM TESTB
WHERE ID = 5
)
AS AA ;
END
//
呼び出し
CALL TEST()//

で、こうすると全件ヒットしたのが出てきてしまうので
呼び出すときに、
CALL TEST(1,10,@cnt)//
みたいな方法で呼び出して、
ストアドプロシージャ内で、LIMITを付与し、取得するデータを制限したいのと
さらに、全件の件数だけ取得したいです。

わかる方、いましたら、ご協力お願いします。

回答の条件
  • 1人3回まで
  • 13歳以上
  • 登録:2010/03/19 19:29:12
  • 終了:2010/03/26 19:30:03

回答(5件)

id:aside No.2

aside回答回数339ベストアンサー獲得回数312010/03/20 15:25:45

ポイント23pt
delimiter //
CREATE PROCEDURE TEST(IN startIdx INT, IN endIdx INT, OUT cnt INT)
BEGIN
	SELECT COUNT(*) INTO cnt FROM
	(
		SELECT TEST1, TEST2
		FROM TESTA
		WHERE ID = 4
		UNION ALL
		SELECT TEST3, TEST4
		FROM TESTB
		WHERE ID = 5
	);
	SELECT HTL.TEST1, HTL.TEST2 FROM
	(
		SELECT TEST1, TEST2
		FROM TESTA
		WHERE ID = 4
		UNION ALL
		SELECT TEST3, TEST4
		FROM TESTB
		WHERE ID = 5
		LIMIT startIdx-1, endIdx
	)
	AS AA ;
END
id:hopefully

ERROR 1221 (HY000): Incorrect usage of UNION and INTO

という風になってしまいます・・

なんでだろう・・

2010/03/23 12:08:56
id:Km1967 No.3

Km1967回答回数224ベストアンサー獲得回数352010/03/20 16:00:46

ポイント22pt

http://dev.mysql.com/doc/refman/5.1/ja/call.html

動かしてはおらんが、何もないよりましだろう。

delimiter //
CREATE PROCEDURE TEST(st INT, ed INT, INOUT c INT)
BEGIN
  SELECT count(*) INTO c FROM (
    SELECT TEST1, TEST2 FROM TESTA WHERE ID = 4
    UNION ALL
    SELECT TEST3, TEST4 FROM TESTB WHERE ID = 5
  ) AS AA;
  SELECT TEST1, TEST2 FROM (
    SELECT TEST1, TEST2 FROM TESTA WHERE ID = 4
    UNION ALL
    SELECT TEST3, TEST4 FROM TESTB WHERE ID = 5
  ) AS AA
  LIMIT st, ed;
END
//
delimiter ;
SET @cnt = 0;
CALL TEST(1, 10, @cnt);
SELECT @cnt;

話は変わるが、これはphpとの組み合わせで使うことになるのであろう? VIEWのほうが良いかもしれぬぞ。

mysql_num_rowsで総数を数え、LIMITを組み込んだSQLを発行という流れなど、よければ、少し考えてみるよろし。

id:hopefully

ありがとうございます。

少し、質問なんですが

なぜ、PHPで使用する場合、VIEWの方がいいのでしょうか?

もし、よろしければ教えていただけませんか?

2010/03/22 23:24:11
id:Km1967 No.4

Km1967回答回数224ベストアンサー獲得回数352010/03/23 02:01:56

ポイント22pt

MySQLのストアドはCREATE時には簡単な構文チェックのみで実行コードへの変換等は行われない。すなわち、呼び出す度に変換が行われ、そのあと実行という2段階になる。もっと重要な問題がクエリーキャッシュが効かない事。(下記参照)ストアドの利用は高速化という意味での恩恵はあまりないどころか下手に使うと負荷増大&低速化という可能性が高まる。

http://dev.mysql.com/doc/refman/5.1-olh/ja/query-cache-operation...

次のようなクエリーにはキャッシュは使用されません。

*クエリーが外部クエリーのサブクエリーである場合

*ストアドファンクション、トリガー、イベントなどのボディ内で実行したクエリー

ストアドを共通ルーチンと位置付けて管理していくというのであれば、そちらのほうが高速化よりも重要かもしれぬが、当然ながらphpファイルの一覧とは別にストアドの一覧のようなものを作成して、管理運営していかねばならぬという管理コストも発生する。


対してVIEWはテーブルに近い感覚で動作し、扱う事ができる分、ストアドよりは比較的、お気軽お手軽。

しかし、INDEXを使えないなど欠点は多い(下記参照)し、サブクエリ内でUNIONを使っておるからこちらもクエリキャッシュは効かんはずじゃ、よりパフォーマンスを求めるとなるとテーブル構成やアプリ側の対処までの広範囲で設計見直したほうが良いじゃろう。

http://dev.mysql.com/doc/refman/5.1/ja/view-restrictions.html


以上簡単じゃが、データベース設計段階で考えるべきお話じゃから、このあたりまでにする。がんばりなされ。

id:hopefully

なるほど、MYSQLのストアドはあまり扱いずらいのですね・・

ですが、今回のメインはストアドを共通ルーチンとして管理というのが

主なので、今回はいいと思います。

とりあえず、上記クエリを実行したのですが・・

試したのですが・・

MySQL server version for the right syntax to use near 'st, ed;

となってしまいますね。。

なんででしょうかね・・

自己解決しました。すいません、色々と。

2010/03/23 15:18:02

質問者が未読の回答一覧

 回答者回答受取ベストアンサー回答時間
1 chuken_kenkou 722 671 54 2010-03-23 22:21:24

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません