SOFTELメモ Developer's blog

会社概要 ブログ 調査依頼 社員募集 ...

プリペアドステートメント?

問題

ぷりぺあどすてーとめんとってなんですか?

SQLに?がたくさん入ってるし、よくわかりません。

答え

php の PDO::prepare() とかから入ると謎の機能に見えるけど、

プリペアドステートメントっていうのはデータベースの機能で、MySQLは5.1からサポートしてる。PostgreSQLとかOracleとかSQLserverとかは昔から。

MySQLで、逐一SQLを書くと、こんな感じで使える。

mysql> PREPARE stmt1 FROM 'SELECT member_id from member where address=?';
mysql> SET @a = '神戸市';
mysql> EXECUTE stmt1 USING @a;
+------------+
| member_id |
+------------+
| 123456789 |
+------------+

何がいいの?って、安全なことが第一。

addslashes とか mysql_real_escape_string などの関数で自分でエスケープしないですむ。

同じ構文ならパラメータをとっかえひっかえ実行できる。

PREPARE foo FROM 'insert into member (member_name) values (?)';
SET @x = '佐藤';
EXECUTE foo USING @x;
SET @x = '高橋';
EXECUTE foo USING @x;
SET @x = '山田';
EXECUTE foo USING @x;
......
......

phpのPDO使うと、こんな風になる

$db = new PDO('mysql:host=localhost;dbname=test')
$s = $db->prepare('insert into member (member_id, address) values (?, ?)');
$s->execute(array('x123456', '岐阜市'));
$s->execute(array('x123457', '名古屋市'));
$s->execute(array('x123458', '大垣市'));
......
......

データベースが PREPARE をサポートしてないときはphp側がエミュレートしてるけど、基本的にはデータベースの機能。

PDOのMySQLドライバはデフォルトはエミュレートする(ので古いMySQL相手でも問題ない)。

setAttribute(PDO::ATTR_EMULATE_PREPARES, false) すると、エミュレートじゃなくてデータベースの機能をちゃんと使う。

ちゃんと使いたいけど、発行するSQLが増えるので(PREPARE / EXECUTE)、あえてエミュレートの方でよしとすることもあるらしい。

関連するメモ

コメント