MySQL&ADOdbのを使う時にExecuteではまる

ADOdbでExecuteを使う時に、?を使って値を変換してSQLを実行してくれるっていう使い方がある。
$conn->Execute("SELECT * FROM TABLE WHERE COND=?", array($val));
みたいな。

で、自分はテーブル名も入れたかったので、こうやった。
$conn->Execute("SELECT * FROM ? WHERE COND=?", array($table, $val));
まあ、テーブル名を追加しただけなんだけど、これが上手く動かない。
エラーメッセージには文法的に違うとしか出てこなくて、途方にくれた。

みんな、出来ているようなのになぜ?ということで、休みの日を使って調べてみた。
で、結局分かったのが、こんなSQLを発行されていた。
"SELECT * FROM 'tablename' WHERE COND='1'";
ここで、tablenameを"'"で囲っていることが気になり、それを外してみるとビンゴ!

以前、ADOdbを調べた時にデータベースのソフトによって、何で囲うかは判別していたような気がしたので、今回はもっと深いところまで追ってみた。
まず囲う文字のことを「識別子引用符文字」ということ。
なげえ。

で、一応qstr()って囲ってくれる関数はあるんだけど、それはMySQL独自の文字で囲うってよりもカラムの値を囲む為のもので、テーブル名とかまでは考慮していない模様。
テーブル名とかそういうのは、nameQuoteって値に入っているみたいだけど、それで囲ってくれるような関数は用意されていないっぽい。
(内部ではあるみたいだけど、外からは参照できなかったかな)

なんで直接その値を参照すれば良い。

まあ、見栄えは悪いけど様はこういうことだ。
$conn->Execute(
    "SELECT * FROM ".$conn->nameQuote.$tablename.$conn->nameQuote.
    " WHERE ".$conn->nameQuote."COND".$conn->nameQuote."=?", array($val));

ちなみにEthnaのEthna_DB_ADOdbクラスでは、quoteIdentifier()って関数が用意されているので、楽チン。
$this->db->query(
    "SELECT * FROM ".$this->db->quoteIdentifier($tablename).
    " WHERE ".$this->db->quoteIdentifier('COND')."=?", array($val));

自分の気づく遅さが嫌になる&またまた勉強になった。
Ethnaすげえ。

コメント

アーカイブ

2012

  • 01
  • 02
  • 03
  • 04
  • 05
  • 06
  • 07
  • 08
  • 09
  • 10
  • 11
  • 12

2011

2010

2009

2008

2007

コンタクト

longkey1[at]gmail[dot]com