Query Go
識別子のクォート方法 - 識別子クォートと大文字小文字 ("" / `` / []) の使い方・オプション・サンプル

識別子のクォート方法 - 識別子クォートと大文字小文字 ("" / `` / [])

列名やテーブル名のクォート記号は RDBMS で異なる。ダブルクォート / バッククォート / 角括弧、および大文字小文字の扱いを比較

概念図

識別子クォートと大文字小文字 ("" / `` / []) diagram

構文

sql
"column"  /  `column`  /  [column]

サンプル

予約語や空白を含む識別子をクォートする書き方

sql
-- ANSI 標準 (PostgreSQL / SQLite / Oracle / SQL Server)
SELECT "user name" FROM "User";

-- MySQL デフォルト
SELECT `user name` FROM `User`;

-- SQL Server 固有 (T-SQL)
SELECT [user name] FROM [User];

-- MySQL で ANSI_QUOTES を有効にすると " も識別子クォートになる
SET sql_mode = 'ANSI_QUOTES';
SELECT "user name" FROM "User";  -- これで動く

なぜクォート記号が分かれたのか

ANSI SQL 標準では識別子のクォートに ダブルクォート " を使い、文字列リテラルには シングルクォート ' を使います。PostgreSQL / SQLite / Oracle / SQL Server はこの標準に従っています。

MySQL は当初からダブルクォートも文字列リテラルとして許容していたため、識別子クォート用に バッククォート ` を採用しました。SQL Server は追加で T-SQL 固有の 角括弧 [ ] もサポートします。

RDBMS 別比較表

RDBMS識別子クォート文字列リテラル大文字小文字
PostgreSQL"col"'text'クォート無し: 小文字に畳む / 有り: 区別
MySQL`col` (ANSI_QUOTES で " も可)'text' or "text" (既定)OS 依存 (Linux: 区別 / Win: 無区別)
SQLite"col" / `col` / [col]'text'無区別 (ASCII)
SQL Server[col] / "col" (QUOTED_IDENTIFIER 有効時)'text'照合順序 (collation) で決まる、既定は無区別
Oracle"col"'text'クォート無し: 大文字に畳む / 有り: 区別

大文字小文字の畳み込みに注意

PostgreSQL は クォート無しの識別子を小文字に畳みますCREATE TABLE "User" のように大文字で作ると、以降は SELECT * FROM "User" のように常にクォート付きで書かなければアクセスできません。

Oracle は逆に大文字に畳みます。Rails や Hibernate の自動生成 SQL が大文字テーブルを作ってしまい、手書きクエリと衝突する事故が多発するのはこのためです。

PostgreSQL / Oracle 系では、テーブル・列名は原則クォートしない(=小/大文字のみ)で統一するのが安全です。

sql
-- PostgreSQL
CREATE TABLE "User" (id INT);    -- 「User」という名で作られる
SELECT * FROM User;              -- エラー (user に畳まれる)
SELECT * FROM "User";            -- OK

CREATE TABLE users (id INT);     -- 推奨: クォート無しで小文字統一
SELECT * FROM Users;             -- OK (users に畳まれる)

移植時の落とし穴

  • MySQL の "text" を識別子と誤解: デフォルト設定では文字列として動くが、ANSI_QUOTES モードを有効にすると識別子として解釈されるためクエリが壊れる
  • SQL Server の [col] は他で動かない: 他 RDBMS に移すなら "col" に置換すればよいが、予約語対策でブラケットを多用している T-SQL はコード量が増える
  • MySQL のテーブル名 OS 依存: Windows ローカルで動いていた FROM Users が Linux 本番では FROM users しか通らない事故がある。lower_case_table_names 設定を揃える
  • 予約語を列名にしない: order, user, group, type などは将来の予約語追加で地雷化する。クォートに頼らず避ける
  • SQL Server の QUOTED_IDENTIFIER: OFF だと "abc" が文字列リテラルになる。インデックス付きビューや計算列の定義時には必ず ON が必要

関連トピック