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

単純に
select
count(*)
from
(
元のSELECT文
) test
とか?
なんか勘違いしてるかな。
MySQL 4.0 系なのでサブクエリ使えんとです。
ガーン orz
まったくエントリーと関係のない話で申し訳ないんだけど
http://www.willcom-inc.com/ja/lineup/ws/003sh/
これどうよ?
即ゲットしてしまいそうな悪寒w
maji かんけーないじゃん。
まあこれを使って何をするかって話だなあ。
しかし世のギーク達は何をしでかすかわからんわけで、場合によってはとんでもないオモチャに化ける可能性もあるので、その辺チェックしつつ暫し様子見。
しかしでかすぎてポケットにいれたらモッコリしすぎな感じがする。