PDOにおいて、テーブル名やフィールド名で予約語を使いたい


最終更新: 2013-08-15

【SET sql_mode='ANSI_QUOTES' について】

MySQLの場合だけ実行しないとエラーが発生することがわかりました。

該当箇所のコードを修正しています。

Yahoo!知恵袋で質問しました。
http://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1399757013


そのまとめを。
つまり、
『SET sql_mode='ANSI_QUOTES'』を実行した上で、
識別子(データベース名やテーブル名やフィールド名)を全てダブルクオートで囲めば、
どのDBでも共通して実行できます。

ごく普通のSQL

SELECT * FROM posts WHERE name LIKE '%検索語%'
ごく普通のPDOのプリペアド・ステートメントでの記述

$statement = $db->prepare('SELECT * FROM posts WHERE name LIKE :keyword');
どのDBでも共通して予約語を使える記述
上ではテーブル名に予約語は使えません。(MySQLでの『explain』など)
引用符で囲めばいいのですが、MySQLではバッククォート(`)を使うので各DB共通の記述にならず、せっかくのPDOを使う意味が…orz
そこで、使用する引用符の設定を変更します。

$db->exec("SET sql_mode='ANSI_QUOTES'");
$statement = $db->prepare('SELECT * FROM "explain" WHERE "name" LIKE :keyword');
実際の記述
実際には、テーブル名もあらかじめ変数などに格納されているはずなので、こんなふうになると思います。

$dsn = 'mysql:host=localhost;dbname=acbox;charset=utf8';
$username = 'root';
$password' = '';
$db = new PDO($dsn, $username, $password);

$table = 'explain';
$field = 'name';
$keyword = '%検索語%';

//MySQLの場合のみ実行
if ($db->getAttribute(PDO::ATTR_DRIVER_NAME) == 'mysql') $db->exec("SET sql_mode='ANSI_QUOTES'");

$statement = $db->prepare('SELECT * FROM "' . $table . '" WHERE "' . $field . '" LIKE :keyword');
$statement->bindParam(':keyword', $keyword, PDO::PARAM_STR);
$statement->setFetchMode(PDO::FETCH_ASSOC);
$statement->execute();