PEAR SQL_Parser

ある select SQL 文があって、その実行結果の件数だけを知りたい場合、例えば PHP ならば各 DB 毎に *_num_rows という関数があるのだけれども、実際得られる結果は「すべての結果が出た後に件数を全件舐めて出す」のか「非同期で実行するので件数に信憑性がない」のかよくわからない。前者なら全ての結果を得て、その件数を count していることと何ら変わりない。件数が少なければいいんだけど、多くなると多分凄いことになる。

そもそも偉大なる DBI の本によると、rows() メソッドの項に「ぶっちゃけ怪しいから count(*) しろ」と書いてある。つまり件数だけを知りたいならちゃんと count(*) SQL 文で件数を得た方がよいのだ。

さて、そんなシチュエーションにぶち当たってしまった本日。既に SQL 文は存在している。その SQL の件数だけを知りたい。でも count(*) SQL 文は用意できない。そんな場合どうやって count(*) SQL 文に変えたらいいのかなと思っていて引っ張り出してきたのが掲題のパッケージ、SQL_Parser。どうも perl の SQL::Statement からの参照らしい。

要は、SQL 文を一度 Parse して、select column の部分を count(*) に書き換えてしまえばいいというお話。こんな感じ。

<?php
require_once('SQL/Parser.php');
require_once('SQL/Compiler.php');

$sql = '
SELECT
  id, name
FROM
  member
';

$parser = new SQL_Parser();
$parseTree = $parser->parse($sql);
var_dump($parseTree);

$compiler = new SQL_Compiler();
$parseTree['column_names'] = array('count(*)');
var_dump($compiler->compile($parseTree));
?>

結果

array(7) {
  ["command"]=>
  string(6) "select"
  ["column_tables"]=>
  array(2) {
    [0]=>
    string(0) ""
    [1]=>
    string(0) ""
  }
  ["column_names"]=>
  array(2) {
    [0]=>
    string(2) "id"
    [1]=>
    string(4) "name"
  }
  ["column_aliases"]=>
  array(2) {
    [0]=>
    string(0) ""
    [1]=>
    string(0) ""
  }
  ["table_names"]=>
  array(1) {
    [0]=>
    string(6) "member"
  }
  ["table_aliases"]=>
  array(1) {
    [0]=>
    string(0) ""
  }
  ["table_join_clause"]=>
  array(1) {
    [0]=>
    string(0) ""
  }
}

string(27) "select count(*) from member"
 

目的の個所を書き換えるメソッドが実装されていないのが何ともだけれども、とりあえずはこんな感じで使えそう。
ちなみに実際の SQL 文は JOIN, WHERE 込みの SQL だったけど、問題なく元通りに。なかなか面白い。

トラックバック(0)

このブログ記事を参照しているブログ一覧: PEAR SQL_Parser

このブログ記事に対するトラックバックURL: http://hatotech.org/mt-admin/mt-tb.cgi/546

コメント(5)

anonymous :

単純に

select
count(*)
from
(
元のSELECT文
) test

とか?

なんか勘違いしてるかな。

くまっち :

MySQL 4.0 系なのでサブクエリ使えんとです。

anonymous :

ガーン orz

とどめくす :

 まったくエントリーと関係のない話で申し訳ないんだけど

http://www.willcom-inc.com/ja/lineup/ws/003sh/

これどうよ?

即ゲットしてしまいそうな悪寒w

くまっち :

maji かんけーないじゃん。

まあこれを使って何をするかって話だなあ。
しかし世のギーク達は何をしでかすかわからんわけで、場合によってはとんでもないオモチャに化ける可能性もあるので、その辺チェックしつつ暫し様子見。

しかしでかすぎてポケットにいれたらモッコリしすぎな感じがする。

コメントする

このブログ記事について

このページは、が2005年11月 8日 20:29に書いたブログ記事です。

ひとつ前のブログ記事は「DAoC: 斗え!Hatotech ファミリー 番外編」です。

次のブログ記事は「maple: 規約を隠すための Generate」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

Powered by Movable Type 4.01