MySQLデータベースを生成する場合、CREATE TABLE IF NOT EXISTSを使うと、作成済みのテーブルを作ろうとするエラーを防げます。しかし、その後のスクリプトの処理が面倒になるっぽいです。
元ネタはPHP逆引きレシピ 第2版 (PROGRAMMER’S RECiPE)のレシピ270です。コードのライセンスは修正BSDです。
$sql = "CREATE TABLE IF NOT EXISTS example (
id INT(11) NOT NULL auto_increment PRIMARY KEY,
message TEXT
) DEFAULT CHARSET=utf8";
try {
$db = new PDO($dsn,$dbUser,$dbPass);
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$db->query($sql);
echo 'Table created!';
} catch (PDOException $e) {
echo htmlspecialchars($e->getMessage(),ENT_QUOTES,'UTF-8');
}
テーブルを作成するSQLを実行するスクリプトです。テーブルexampleが無ければ作成し、Table created!を出力します。
では、テーブルexampleがある場合はどうなるでしょうか。SQL内にCREATE TABLE IF NOT EXISTSがあります。これは「テーブルが無い場合は作成しなさい」という命令なので、実行すると「テーブルがあるので何もしなかったよ(エラーではないよ)」と返ってきます。そうするとスクリプトは正常に実行されて、(実際には何もしていないのに)Table created!を出力します。
db->query($sql);の結果が正常終了となると、スクリプト側での判定(テーブルを作ったのか/テーブル作成済みで何もしなかったのか)は難しそうです。テーブル作成後に初期データ流し込み、という処理を書いた場合、このコードを二回実行すると、テーブル作成は一回だけですが初期データが二回挿入されます。この辺、うまく処理できると嬉しいのですが。
なお、CREATE TABLEだけを記述した場合は、echo htmlspecialchars($e->getMessage(),ENT_QUOTES,'UTF-8');が
SQLSTATE[42S01]: Base table or view already exists: 1050 Table 'example' already exists
というエラーを表示します。なのでテーブルが既に存在している場合の処理を変える事ができます。だからといって、わざわざIF NOT EXISTSを外すのもイマイチかな、と思います。