データベースのテーブル名で大文字と小文字は区別される?
embulk-output-oracleを使っている方から、テーブルがあるのにエラーになってしまう、という問い合わせがあった。
調べてみると、テーブル名は大文字なのに、設定ファイルは小文字で書いてある。
普通にOracleでSQLを書くと大文字/小文字は区別されないが、embulk-output-jdbcではテーブル名を引用符で囲んだSQLを構築する。
Oracleでは引用符で囲むと大文字/小文字が区別されてしまうのだ。
うーん、各DBMSで大文字/小文字が区別されるかどうか、まとめておいた方がよさそうだ。
Oracle
9. 引用符のない識別子は、大/小文字が区別されません。 引用符のない識別子は大文字として解析されます。 引用識別子では、大文字と小文字が区別されます。
実際にやってみた。
SQL> CREATE TABLE TEST(ID CHAR(2)); 表が作成されました。 SQL> SELECT * FROM TEST; レコードが選択されませんでした。 SQL> SELECT * FROM test; レコードが選択されませんでした。 SQL> SELECT * FROM "TEST"; レコードが選択されませんでした。 SQL> SELECT * FROM "test"; SELECT * FROM "test" * 行1でエラーが発生しました。: ORA-00942: 表またはビューが存在しません。
MySQL
MySQL :: MySQL 5.6 リファレンスマニュアル :: 9.2.2 識別子の大文字と小文字の区別
データベース内の各テーブルも、...ファイルに対応しています。 ... この結果、基になるオペレーティングシステムで大文字と小文字が区別されるかどうかが、 データベース名、テーブル名、およびトリガー名で大文字と小文字が区別されるかどうかに影響します。 これは、Windows ではこれらの名前は大文字と小文字が区別されませんが、 多くの Unix では大文字と小文字が区別されることを意味します。
なるほど。OSによって違うのか。
MySQL :: MySQL 5.6 リファレンスマニュアル :: 9.2 スキーマオブジェクト名
引用符と大文字/小文字の区別については書かれていなかった。
実際Windowsで試してみると、区別されなかった。
mysql> create table xyz (id char(2)); Query OK, 0 rows affected (0.06 sec) mysql> select * from xyz; Empty set (0.00 sec) mysql> select * from XYZ; Empty set (0.00 sec) mysql> select * from `xyz`; Empty set (0.00 sec) mysql> select * from `XYZ`; Empty set (0.00 sec)
Linuxだと大文字と小文字は区別される。
mysql> create table xyz (id char(2)); Query OK, 0 rows affected (0.02 sec) mysql> select * from xyz; Empty set (0.00 sec) mysql> select * from XYZ; ERROR 1146 (42S02): Table 'test.XYZ' doesn't exist mysql> select * from `xyz`; Empty set (0.00 sec) mysql> select * from `XYZ`; ERROR 1146 (42S02): Table 'test.XYZ' doesn't exist
PostgreSQL
キーワードと引用符付きでない(クォートされていない)識別子は大文字と小文字を区別しません。
なるほど、逆に、引用符を付けると大文字/小文字が区別されるのかな。
postgres=# create table xyz(id char(2)); CREATE TABLE postgres=# select * from xyz; id ---- (0 行) postgres=# select * from XYZ; id ---- (0 行) postgres=# select * from "xyz"; id ---- (0 行) postgres=# select * from "XYZ"; ERROR: リレーション"XYZ"は存在しません 行 1: select * from "XYZ"; ^
確かに区別された。
SQL Server
テーブル名、ビュー名、列名など、データベース内のオブジェクトの識別子には、 データベースの既定の照合順序が指定されます。 たとえば、大文字と小文字を区別する照合順序が指定されたデータベースでは、 同じ名前で大文字と小文字のみが異なる 2 つのテーブルを作成できますが、 大文字と小文字を区別しない照合順序が指定されたデータベースでは作成できません。
SQL Serverでは、照合順序の設定により、どちらでも選べるようだ。
例えば、"Japanese_CI_AS"のように"CI"を含む場合は区別しない。"CS"を含む場合は区別する。
引用符(""や[])と大文字/小文字の区別については書かれていない。
"Japanese_CI_AS"で以下を実行したら、正常に実行できた。
CREATE TABLE XYZ(ID CHAR(2)); SELECT * FROM XYZ; SELECT * FROM xyz; SELECT * FROM "XYZ"; SELECT * FROM "xyz"; SELECT * FROM [XYZ]; SELECT * FROM [xyz];
まとめ
まとめると、こんな感じか。
DBMS | 大文字と小文字の区別 |
---|---|
Oracle | 引用符で囲むと区別される |
MySQL | 大文字と小文字のファイル名を区別するOSでは区別される |
PostgreSQL | 引用符で囲むと区別される |
SQL Server | 照合順序の設定によっては区別される |
embulk-output-jdbcではテーブル名を引用符で囲むので、OracleとPostgreSQLでは要注意だ。
Oracle | 12c |
MySQL | 5.6 |
PostgreSQL | 9.4 |
SQL Server | 2012 |