第2章 言語構造

リテラル、識別子、予約語、コメント構文

リテラル(literal

リテラルや識別子など、SQLの基本となる要素を説明します。

リテラルとは、変数や定数以外の、数値や文字列など表記どおりの値の総称です。256、"Rhythm"、2007-10-01といった数値や文字列、日付がリテラルにあたります。

SQLのリテラル値
  • 文字列
  • 数値
  • 16進値
  • ブール値
  • NULL値

文字列

文字列の表現方法

文字列はシングルクォート( ' )、もしくはダブルクォート( " )で囲みます。

'文字列'
"文字列"

下記のクエリはWHERE句の検索条件の値に文字列を指定しています。

SELECT * FROM table WHERE name = 
'テキスト';

※標準SQLでは、文字列はシングルクォートで囲みますが、MySQLなど多くのRDBMS製品はダブルクォートにも対応しています。多くのプログラム言語ではシングルクォートで囲んだ変数は展開しないという決まりがあるため、SQLはシングルクォートで文字列を囲んだほうが使いやすいでしょう。

エスケープシーケンス

SQLには、ディスプレイに表示されない文字や、紛らわしい文字を区別する為の『エスケープシーケンス』が用意されています。

たとえば、文字列中で改行文字を使いたい場合は、次のようにエスケープシーケンスで改行文字を表現することができます。

SELECT '---\n---';
> ---
> ---
エスケープシーケンス一覧
エスケープシーケンス 意味
\0  ASCII 0 (NUL)
\n 改行文字
\t タブ文字
\r リターン文字
\b バックスペース文字
\z ASCII 26 (Control-Z)。
\'  シングルクォート( ' )
\" ダブルクォート( " )
\\ バックスラッシュ( \ )文字
\% % 文字
\_ _ 文字

クォートの中で同じクォートを使いたい場合は、エスケープシーケンスでエスケープする以外に、他のクォートを使います。たとえば、シングルクオート( ' )を文字列中で使いたい場合は、ダブルクォートで文字列を囲みます。

SELECT "You're just too good to be true.";
> You're just too good to be true.

BLOBフィールドでのエスケープシーケンス

BLOBフィールドにバイナリデータを挿入するような場合は、次の特殊文字をエスケープする必要があります。

変換が必要な文字 エスケープシーケンス
NUL \0
\ \\
' \'
" \"

Perlでは、DBIパッケージのquoteメソッドを使用して、特殊文字を適当なエスケープシーケンスに変換できます。


数値

数値は、普段使うような整数や浮動小数点の表記法と同じです。

数値リテラルの一覧
数値リテラル 説明
整数

12345

整数は数字の並びです。

16進数

0x9F1F

16進数は0xで始まります。

浮動小数点

12.34

整数と小数の間にドット( . )を挟みます。

指数

.234e-2

指数記法で表される数値は、eの後に指数を表す正または負の数がつきます。

上記の型すべては負数を表すために - 記号を先頭につけます。


16進値

16進値は、数値のコンテキストでは整数(64 ビット精度)のように動作し、文字列のコンテキストではバイナリ文字列のように動作します。その際は16進数の各ペアが1文字に変換されます。

SELECT x'4D7953514C';
-> MySQL

ブール値

ブール値とは、条件が真であるかどうかを表す値のことです。SQLではブール値としてTRUEとFALSEの2つの定数が用意されています。TRUEは 1、FALSEは 0 として評価されます。定数名は大文字/小文字の区別がなされません。

SELECT TRUE, true, FALSE, false;
> 1 1 0 0

NULL値

NULL値は値の未定義を意味する値で、0 や空白文字ではありません。NULLは値が未定という意味を持っているので、NULL同士でも等しくならず、計算や比較には使えません。

テキストファイルの読み込みや書き出し時は、NULLは\Nで表現されます。


識別子

命名規則と表記法

命名規則

SQL構文のなかでデータベース名、テーブル名、インデックス名、フィールド名、エイリアス名といったオブジェクトの名称を指定する際は、下記のような規則に従う必要があります。

識別子 長さ 使用可能な文字
データベース 64 スラッシュ( / )を除くディレクトリ名として許される全ての文字。
テーブル 64 スラッシュ( / )とドット( . )を除くファイル名として許される全ての文字。
フィールド 64 全ての文字。
エイリアス 255 全ての文字。

注意: 上記に加え、識別子内にASCII(0)とASCII(255)は使えません。

識別子が予約語と同じ、または特殊文字を含む場合は、MySQLであればバッククォート( ` )で囲むことで識別子であることを明示できます。

SELECT * FROM `select`;

Oracle、PostgreSQLの場合はダブルクォーテーション( " )、SQL Serverの場合はスクエアブラケット( [] )で囲みます。

#Oracle、PostgreSQL
SELECT * FROM "select";

#SQL SERVER
SELECT * FROM [select]; 

識別子の先頭に数字を使う場合は注意しましょう。1e
のような名前を条件式で使用した場合、フィールド名としてではなく数値として解釈されます。

※ 1e
のような名前は使用しないことを勧めます。計算の際、名前としてではなく、表現 1e + 1 として、または数値 1e+1 として解釈されます。

命名規則

意味のある名前を選ぶ

テーブル名を定義する際に、TABLE01、TABLE02といった名前を使うとどのようなテーブルかそのままではわかりません。顧客情報を扱うテーブルであればcustomer、商品を扱うテーブルであればgoodsなど、名前から役割を連想しやすい名前をつけるようにしたほうがよいでしょう。

大文字と小文字の使い分けを一定にする

システムによっては大文字・小文字を区別したり、しなかったりするので、最初に大文字は使わない、小文字は使わないなどの規則を決めるべきです。ほとんどの場合は小文字のみ使用で統一されていますが、大文字のみで命名しても特に実害はありません。大文字、小文字を混在させるようなことは避けたほうがよいでしょう。

一貫した略記法を使う

フィールド名などは意味をそのままフィールド名にしたりすると、非常に長くなる場合があります。 そのまま長い名称を使うか、文字列を短く略すかは最初に決めておくほうがよいでしょう。たとえばディレクトリ名を格納するフィールド名の場合、dir_nameでも、directory_nameでもよいですが、どちらか一方の命名法で統一するべきです。

また、単語を省略する際は、母音を省略しないほうがよいでしょう。directoryの母音を省略するとdrmとなりますが、何を省略したのかわかりにくいです。

アンダスコアを使って、読みやすく、意味のわかる名前をつける

長い識別子の場合には、アンダーバー( _ )を使って単語を区切るようにしましょう。一般的に"as_soon_as"のほうが"AsSoonAs"よりも読みやすいです。

固有名詞をデータベースオブジェクトの名前に使わない

社名や製品名は変わることがあります。そういった固有名詞は永続性にかけるので、テーブル名などに使うのは避けたほうが良いでしょう。

あってもなくても変わらない接頭辞や接尾辞を使わない

データベース名として接頭辞に"DB"を使ったり、テーブル名の接頭辞に"TB"をつけるのは余計です。意味のある接頭辞や接尾辞は積極的に使っても良いでしょう。

名前の修飾

データベース名やテーブル名、それにフィールド名を付ける際に発生するエラーの原因の大半は、名前の衝突にあります。たとえば、同じデータベース内で既にあるテーブル名でテーブルを作成しようとすると、エラーになります。1つのデータベースの中に同じ名前のテーブルや、1つのテーブルの中に同じ名前のフィールドなどを作成することは出来ません。

名前空間が違う場合、たとえば、別々のデータベースに同じ名前のテーブルがあっても問題ありません。それは、『名前の修飾』によって名前の衝突を避けることができるからです。名前の修飾の表記方法は、「データベース名.テーブル名」のように間にドット(
. )を挟みます。たとえば、"db1"データベースと"db2"データベースに、"mytable"という同じ名前のテーブルがある場合、次のように名前の修飾を行います。

SELECT * FROM db1.mytable, db2.mytable; 

これは、選択しているデータベースとは違うデータベースを指定する際にも同じことがいえます。

#db1 を選択
USE db1;

#名前の修飾を行って db2 を SELECT
SELECT * FROM db2.mytable; 

コメント構文

コメントは、プログラムの実行に影響を与えない説明文です。

# この行はコメントです
SELECT * FROM table_name; # ここからコメントです

シャープ( # )以降から改行までの文字列がコメントになります。

また、複数行のコメントをサポートするために、/* ... */ という書式が用意されています。

/*---------------------------------
複数行による
コメントが可能です。
---------------------------------*/
SELECT * FROM table_name;
...

複数行コメントにはいくつかの注意点があります。シングルクウォートとダブルクォート文字は、たとえコメントの中であっても文字列の開始となります。ですから、文字列の終わりを示すクォートがない場合、正常な動作を期待することはできません。また、セミコロンは本来の機能どおりSQL構文の終了を示し、それ以降の文字列は次の構文の開始とみなされます。


キーワードと予約語

SELECTやINSERTのようなあらかじめ使うことが決められている語句を『予約語』と呼びます。予約語には、大文字・小文字の区別がありません。ですから、SELECT、select、Selectなどはどれも同じ意味です。

予約語はテーブル、フィールド名としての使用を禁止されています。たとえば、SELECTという語句はテーブル、およびフィールド名として使用することはできません。

MySQLの予約語の一覧
語句
ACCESSIBLE ADD ALL
ALTER ANALYZE AND
AS ASC ASENSITIVE
BEFORE BETWEEN BIGINT
BINARY BLOB BOTH
BY CALL CASCADE
CASE CHANGE CHAR
CHARACTER CHECK COLLATE
COLUMN CONDITION CONSTRAINT
CONTINUE CONVERT CREATE
CROSS CURRENT_DATE CURRENT_TIME
CURRENT_TIMESTAMP CURRENT_USER CURSOR
DATABASE DATABASES DAY_HOUR
DAY_MICROSECOND DAY_MINUTE DAY_SECOND
DEC DECIMAL DECLARE
DEFAULT DELAYED DELETE
DESC DESCRIBE DETERMINISTIC
DISTINCT DISTINCTROW DIV
DOUBLE DROP DUAL
EACH ELSE ELSEIF
ENCLOSED ESCAPED EXISTS
EXIT EXPLAIN FALSE
FETCH FLOAT FLOAT4
FLOAT8 FOR FORCE
FOREIGN FROM FULLTEXT
GRANT GROUP HAVING
HIGH_PRIORITY HOUR
_MICROSECOND
HOUR_MINUTE
HOUR_SECOND IF IGNORE
IN INDEX INFILE
INNER INOUT INSENSITIVE
INSERT INT INT1
INT2 INT3 INT4
INT8 INTEGER INTERVAL
INTO IS ITERATE
JOIN KEY KEYS
KILL LEADING LEAVE
LEFT LIKE LIMIT
LINEAR LINES LOAD
LOCALTIME LOCALTIMESTAMP LOCK
LONG LONGBLOB LONGTEXT
LOOP LOW_PRIORITY MASTER_SSL_VERIFY
_SERVER_CERT
MATCH MEDIUMBLOB MEDIUMINT
MEDIUMTEXT MIDDLEINT MINUTE
_MICROSECOND
MINUTE_SECOND MOD MODIFIES
NATURAL NOT NO_WRITE
_TO_BINLOG
NULL NUMERIC ON
OPTIMIZE OPTION OPTIONALLY
OR ORDER OUT
OUTER OUTFILE PRECISION
PRIMARY PROCEDURE PURGE
RANGE READ READS
READ_ONLY READ_WRITE REAL
REFERENCES REGEXP RELEASE
RENAME REPEAT REPLACE
REQUIRE RESTRICT RETURN
REVOKE RIGHT RLIKE
SCHEMA SCHEMAS SECOND
_MICROSECOND
SELECT SENSITIVE SEPARATOR
SET SHOW SMALLINT
SPATIAL SPECIFIC SQL
SQLEXCEPTION SQLSTATE SQLWARNING
SQL_BIG_RESULT SQL_CALC_FOUND
_ROWS
SQL_SMALL_RESULT
SSL STARTING STRAIGHT_JOIN
TABLE TERMINATED THEN
TINYBLOB TINYINT TINYTEXT
TO TRAILING TRIGGER
TRUE UNDO UNION
UNIQUE UNLOCK UNSIGNED
UPDATE USAGE USE
USING UTC_DATE UTC_TIME
UTC_TIMESTAMP VALUES VARBINARY
VARCHAR VARCHARACTER VARYING
WHEN WHERE WHILE
WITH WRITE X509
XOR YEAR_MONTH ZEROFILL

次のシンボルは、ANSI SQLによって却下されていますが、MySQLではテーブル名やフィールド名としての使用を許可されています。

  • ACTION
  • BIT
  • DATE
  • ENUM
  • NO
  • TEXT
  • TIME
  • TIMESTAMP

関連記事