Standing on the Shoulder of Linus

Home / 2013 / 11月 / 22 / CREATE TABLE IF NOT EXISTSは作成済みのテーブルを作ろうとするエラーを防げるが、

CREATE TABLE IF NOT EXISTSは作成済みのテーブルを作ろうとするエラーを防げるが、

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を外すのもイマイチかな、と思います。

Posted in php | Tagged PDO, PHP
← 日本語版が存在しないCMS、Novius OS きんどるどうでしょうで一斉セール開催 →

アーカイブ

人気の投稿とページ

  • キンドル本を印刷する(PDFに変換する)方法
  • 名古屋駅から国際センターまでの道のり(徒歩)
  • AGPL ライセンス(GPLとは似ているが違いもある)
  • 6年使ったイーモバイル(Y!mobile)を解約手続。店頭でSIM返却
  • JP-Secure SiteGuard WP Pluginは不正ログイン防止に役立つか

プロフィール

水野史土:月70万PVホームページ制作会社のレスキューワーク株式会社で、PHPソフトウェアのサポートを行っている。concrete5コミュニティリーダー、Novius OSコアコード貢献者でもある。 詳しくは管理者詳細参照。
大好評WordPress書籍「WordPressユーザーのためのPHP入門 はじめから、ていねいに。」サポートページ
計算フォームでは、雇用保険料の計算、メルカリ利益率計算など、様々な計算式を紹介しています。

Copyright © 2015 Standing on the Shoulder of Linus.