LoginSignup
2
1

More than 1 year has passed since last update.

MySQL で実行したときだけ式の解釈が変わる SQL 文

Posted at

MySQL のコメントの仕様は標準 SQL と異なっている.これを利用すると,MySQL で実行したときだけ解釈が変わるようなクエリーを書ける.

標準 SQL と MySQL のコメント

標準 SQL においてコメントは -- で始まり行末で終わる.Oracle Database,Microsoft の SQL のサーバー,PostgreSQL および SQLite ではこの形式でコメントを書ける.

select
    *  -- This is a comment
from
    t
where
    t.col1 = 1
    --and t.col2 = 2  -- Commented out

MySQL にはコメントのスタイルがいくつかあるが,-- で始める場合はその直後にスペースが必要となる1.コメントアウトするのが若干面倒になりそうだが,この規則は自動生成のクエリーがおかしくなることを防いでいる.

公式ドキュメンテーションいわく,

UPDATE account SET credit=credit-payment

というクエリーで payment-1 などの負数を当てはめると

UPDATE account SET credit=credit--1

となる.そうはならんやろここで --1 をコメントとみなすと意図通りの操作にならない.先述の規則によりこれは防がれ,--1 も式の一部として解釈される.

そんな C のマクロに括弧をつけ忘れたような置換をする人にお金を管理させるのは心配である.

式の解釈を変える

先述のコメントの規則により,MySQL と他の RDBMS とで式の解釈が異なるようなクエリーを書ける:2

select
    case 1  --1
        when 1 then 'This is not MySQL'
        when 2 then 'This is MySQL'
    end as message

標準 SQL では --1 がコメントとみなされ,when 1 then の直後の値が case 式 の結果となる.MySQL では --1 が式の一部とみなされ,1 --11 - (-1) すなわち 2 に等しい.したがって when 2 then の直後の値が case 式 の結果となる.

MySQL では C 言語スタイルのコメント(/* Block comment */)を使えるので,次の方法もある.

select
    case 1 when 1  --0 /*
              then 'MySQL considered harmful'
        -- */ then 'I love MySQL'
    end as message

標準 SQL では -- から行末までが無視される.これに対して MySQL では /* から */ までの範囲が無視される.


  1. -- の直後は改行でもいいが,その改行自体でコメントが終わるのであまり実用上の意味はない. 

  2. ただし標準 SQL と Oracle Database では select 文の from 句を省略できない.from dual と書き足せば Oracle でも動く. 

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1