たまに使うと、構文エラーを連発してしまうSQLのif文。
「どうだったっけ?」と迷った時のために、コピペで実行結果を確認できる、SQLのif文サンプルコードをご紹介します。
※サンプルコードは、MySQL用です。
目次
SQLのif文の書き方は、データベースごとに異なる
SQLのif文の構文は、主要データベースだけでも微妙に書き方が異なります。
MySQL、Oracleのif文の構文
IF 条件式 THEN 処理文 ELSEIF 条件文 THEN 処理文 ELSE 処理文 END IF
MySQL :: MySQL 5.6 リファレンスマニュアル :: 13.6.5.2 IF 構文
なお、MySQLのIFステートメントは、ストアドプロシージャまたはストアドファンクション内でのみ使用可能です。
SQL Serverのif文の構文は「THEN」がない
IF 条件式 処理文 ELSE IF 条件文 処理文 ELSE 処理文
SQL Serverの場合は、「THEN」がありません。また、「ELSEIF」は、「ELSE IF」という記述になります。
IF文の終わりを示す「END IF」がないため、処理分が複数行ある場合は「BEGIN」と「END」で処理文を囲む必要があります。
IF…ELSE (Transact-SQL) – SQL Server | Microsoft Docs
SQLのif文のサンプルコード
以下に、コピペで動作を確認できるSQLサンプルコードをご紹介いたします。
データベースとして、MySQLのサンプルデータベースEmployeesを使っています。SQL実行結果の表示にはphpMyAdminを使用。
SQLのif文でNULL判定するサンプルコード
DELIMITER // CREATE FUNCTION CheckNULL(name varchar(30)) RETURNS VARCHAR(20) BEGIN declare msg varchar(20); declare depname varchar(20); select dept_name into depname from departments where dept_no=num; if depname IS NULL then set msg = 'NULL'; else set msg=depname; END IF; END DELIMITER ;
サンプルデータベースemployeesのテーブルdepartmentsを、与えられた引数「name」で検索し、dept_name(部署名)がNULLだったら「NULL」、それ以外なら部署名を返すストアドファンクションです。
departmentsテーブルの中身は以下の通り。
引数にd001(Marketing)を指定して実行した結果は以下の通り。
SET @p0='d001'; SELECT `CheckNULL`(@p0) AS `CheckNULL`;
引数にd010(存在しない部署ID)を指定して実行した結果は以下の通り。
SET @p0='d010'; SELECT `CheckNULL`(@p0) AS `CheckNULL`;
場合によっては、NULLの場合は別の値を返すIFNULL関数を使ったほうが、処理が簡単な場合もあります。Oracle、SQL Serverでは、NVL()という関数が用意されています。
短期集中でWebエンジニアになれるスクールはこちら
SQLのif文でSwitch文のように複数の条件文を指定するには、if文を並べる
DELIMITER // CREATE FUNCTION Switch(num varchar(20)) RETURNS VARCHAR(20) BEGIN declare msg varchar(20); if num = "1" THEN # 処理1 set msg = "case 1"; end IF; if num = "2" THEN # 処理2 set msg = "case 2"; end IF; if num = '3' THEN # 処理3 set msg = 'case 3'; end IF; # 処理4 if num = '4' THEN set msg = 'case 4'; end IF; # else それ以外の処理 if num not in ('1','2','3','4') THEN set msg = 'それ以外'; end if; return msg; END // DELIMITER ;
引数によって、処理する内容を変えたい場合、C言語やJavaっぽくSwitch文のようにコードを書きたくなりますよね。
if文を単純に並べることで、それっぽく記述することができます。
SQLのIF文のネスト(入れ子)するサンプルコード
さらに複雑に、特定の条件下で別のif文を使いたい場合は、入れ子にすることが可能です。
DELIMITER // CREATE FUNCTION NameSearchNest ( name VARCHAR(30)) RETURNS VARCHAR(20) BEGIN declare cnt int; declare msg varchar(20); select count(*) into cnt from employees where employees.first_name=name; if cnt > 0 then set msg=cnt; if cnt > 100 then set msg=concat(msg,'(too many)'); end if; else set msg='Not Found'; end if; return msg;
上記のコードは、employeesテーブルにて、first_nameと引数nameが等しいレコードをカウントし、件数を返します。100件以上なら、「(too many)」を件数の後ろに付加し、0件なら「Not Found」を返します。
引数に「Kyoichi」を指定した実行結果。251人も居る!
引数に「Taro」を指定した実行結果。一人も居ない。
なお、2012年頃のブログに「MySQLのIF文の入れ子にインデント(字下げ)を入れたらエラーになった」という情報がありました。
MySQLのストアドプロシージャでIF文のインデントはNGぽい – Big Bang
最新のMySQLでは、インデントを入れても全く問題ありませんでした。古いMySQLではインデントに関する不具合があったのかも知れません。
if exists句を使って、存在するときのみテーブルやプロシージャをドロップする
同じifでも全くの別物で「if exists句」があります。
テーブルやプロシージャをcreateするSQL内で、「もしすでにテーブルやプロシージャが存在したらdrop」という処理をする際に良く使われます。
以下、テーブル「dtable」が存在する場合のみ、dtableをdropするSQLです。
drop table if exists dtable;
SQLの条件分岐は、 if文よりもcase式が簡単なケースもある
SQLのif文は、バッチ処理的な条件分岐に向いています。しかし、一つのSQL内で、データによって処理内容を変えたい場合などは、case式を使うほうがはるかに簡単です。
関連)SQLのCASE式サンプル集 order byやgroup byとの組み合わせもバッチリ
SQLを学んでWebエンジニアを目指そう
Webエンジニアは、Webサービスを作るエンジニアで非常に人気の高い職種です。
スタートアップやベンチャー企業が中心なので柔軟性のある雇用形態、魅力的な作業環境、面白いプロジェクト、高い報酬など非常に魅力的な求人が多いです。
Ruby on RailsやGo言語を用いたプロジェクトが多く、SQLも重要なスキルとなります。
このブログを運営するプログラミングスクールのポテパンキャンプでは、実践的なカリキュラムと現役エンジニアからのレビュー、そしてポートフォリオ添削や模擬面談などの面談転職サポートにより、最短距離でWebエンジニアを目指すことができます。
Webエンジニアへの転職を考えている方は、是非一度無料カウンセリングへお申込みください。
MySQLは、SQLに「;」(セミコロン)が出現すると、問答無用でSQLを実行する仕様になっています。
ここでは、ストアドファンクションの一部としてセミコロンを使いたいため、一時的に区切り文字を「DELIMITER //」で、「//」に切り替えています。