メニュー 蕭寥亭 検索

開店休業の記

技術系小ネタ

 データベースの PostgreSQL の話です。使ったバージョンは 9 。

 下記のような SQL を書きました(実際にはもっと複雑です)。

  INSERT INTO

   users ( name )

    SELECT

     '鈴木'

    FROM

     users

    WHERE

     NOT EXISTS (

      SELECT

       *

      FROM

       users

      WHERE

       name = '鈴木')

 わかりにくい SQL ですが、これはいったい何がしたいのかといいますと、「テーブル users の列 name に『鈴木』という名前が一つもなければ、テーブル users の列 name に『鈴木』を追加する」というものです。要は、まだ一覧の中にない新しい名前だけを一覧に追加していきたいわけです。

 これ、名前があるかないかを確認する SELECT 文と追加に使う INSERT 文の2つに SQL を分ければ簡単なんですが、できるだけ分けたくなくていろいろ調べてやっと狙い通りのものが書けました( WHERE 句で INSERT の条件を指定しつつ、固定値を SELECT させて INSERT 用の値としているのがミソです)。しかし、一つ重大な欠陥がありました。

 それは最低でも1つはレコードがテーブルにないと、INSERT が行われない、つまり空のテーブルだとどんな名前でも追加できないということでした。

 対策を思案したのですが、良いものが浮かばなくて困りました(予めテーブルにダミーのレコードを1つ入れておけば動くのですが、それはしたくありませんでした)。

 失敗を重ねた挙句、「こんなん動くわけね〜よな」と思いつつ、下記のような SQL を実行してみました。

  INSERT INTO

   users ( name )

    SELECT

     '鈴木'

    WHERE

     NOT EXISTS (

      SELECT

       *

      FROM

       users

      WHERE

       name = '鈴木')

 最初の SQL から5・6行目の

    FROM

     users

を削除したものです。

 これが・・・、動きました、狙い通りに。

 「 FROM 句がない SELECT 文が動くのかよ!!」と仰天しましたが、PostgreSQL のマニュアルを見たら「動作する」とちゃんと書いてありました。よってバグを利用した裏技とかではございません(標準の SQL ではダメらしいですが)。

 あんまり驚いたので、記念に(?)ここに書いておきます。