3C.5 非SELECT文の実行
### 非select文の実行
$res =& $db->query($sql);
if(PEAR::isError($res)){ /* エラー処理 */ }
例題( SQLフォーム ) では全ての非SELECT文を query() メソッドで処理しています。 単一の非SELECT文に対しては query() メソッドが最も使い勝手が良いです。
| メソッド | 説明 |
|---|---|
mixed & DB_common::query ( string $query [, mixed $data = array()]) |
SQL文 $query を実行します。SELECT文が成功した場合は 結果セット( DB_result オブジェクト) を、 非SELECT文が成功した場合は DB_OKを、実行が失敗した場合には DB_Error オブジェクトを返します。 SQL文にプレースホルダを使用している場合、引数 $data を指定してプレースホルダに与える値を指定します。 ※ 引数 $dataに関する注意点は下のexecute()メソッドの説明を参照して下さい。 |
query() メソッドは単一のSQL文を実行しますが、原理的に一対の prepare()/execute() メソッドと同じ動作をします。 例えば上例は、次のように変えても原理的には同じです。(但し、エラー処理やリソースの開放などの処理が加わります)
$sth = $db->prepare($sql); $res =& $db->execute($sth);
| メソッド | 説明 |
|---|---|
resource DB_common::prepare ( string $query ) |
SQL 文の実行を準備します。 成功するとクエリのハンドルを、失敗すると DB_Error オブジェクトを返します。 repareされたSQL文を特にプリペアド文と呼びます。 |
mixed & DB_common::execute ( resource $stmt [,mixed $data = array()]) |
prepare() で準備したSQL 文を実行します。 $stmt には prepare() で返されたクエリのハンドルを指定します。 SELECT文が成功した場合は 結果セット( DB_result オブジェクト) を、 非SELECT文が成功したは DB_OKを、実行が失敗した場合には DB_Error オブジェクトを返します。 SQL文にプレースホルダを使用している場合、引数 $data を指定してプレースホルダに与える値を指定します。 $data に渡す値は、SQL文にとってのリテラルである必要があります。 例えば SQL関数や テーブル名またはカラム名などを渡すことはできません。 それらはprepare() の段階で指定する必要があります。 |
prepare文をネイティブにサポートしているデータベースの場合、 repare() メソッドを実行するとSQL文がコンパイルされます。 従って、繰り返しexecute()するような場合、SQL文を高速に処理できます。
プレースホルダ
例えば、以下のSQL文を見て下さい。
UPDATE syain SET bumon_no=? WHERE syain_name=? SELECT * FROM syain WHERE syain_name = ?
上例の ? をプレースホルダ ( またはワイルドカード ) と呼びます。 prepare()/execute() が最も効率よく働くのはSQL文にプレースホルダを使用している場合です。 なぜなら、プリペアド文は繰り返し execute() で実行することができるからです。 しかもその都度異なった値をプレースホルダ に与えることができるので非常に効率のよいやり方です。
$sth = $db->prepare('INSERT INTO syain VALUES (?, ?, ?)');
$db->execute($sth, array(1,'Suzuki', 3));
$db->execute($sth, array(2,'Yamamoto',1));
$db->execute($sth, array(3,'Tanaka', 2));
プレースホルダには以下の3種類があります。
- ? --- クォート処理する文字列
- ! --- クォート処理しない文字列
- & --- バイナリデータを登録するためにファイル名
これらの文字( ? , ! , & ) を それ自体の文字としてSQL文の中で使用する場合は、 \ を前に付けてエスケープする必要がありますので注意して下さい。 それは、例えば次のような場合です。
SELECT * FROM syain WHERE syain_name like 'Suzuki!%' # これは構文エラーになります!
プレースホルダにはもう1つの利点があります。 それはエスケープとクオート処理を自動で行ってくれる点です。 自前でエスケープまたはクオート処理を行うには以下で説明する escapeSimple() または quotoSmart() を使います。
クオート処理
SQL文では文字列をクォート文字で囲み、NULL値 は 'NULL' と記述するなどの規則があります。 また、文字列中の特殊な文字をエスケープする必要もあります。 このような処理を自前でするのは手間の掛かることです。 PEAR::DBでは、以下に示すような便利なメソッドが準備されています。
| メソッド | 説明 | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
string DB_common::escapeSimple ( string $str ) |
$str に含まれるクォート文字をエスケープします。 例えば、 ' を \' に置き換えます。 用例:
$sql = "SELECT * FROM syain WHERE syain_name = '"
. $db->escapeSimple($name) . "'";
|
||||||||||
mixed DB_common::quoteSmart ( mixed $in ) |
$in にエスケープ処理とクォート処理を施します。 このメソッドを使用すれば、WHERE句、SET句 および VALUES 句で使用できる文字列を生成してくれます。 戻り値は以下のように状況により異なります。
|
手元の環境( PHP5.04/PEAR::DB 1.7.6 )では、 escapeSimple()/quoteSmart() 共にプレースホルダを表す文字 ( ? ! & ) をエスケープしてくれませんでした。 なぜでしょう?詳しい情報をお持ちの方はご教授して下さい。
