Mini SQL 2.0

言語仕様



はじめに

mSQL 言語は ANSI SQL によって定義されている主なサブセットを提供します。 プログラムあるいはユーザが、テーブル構造でデータを貯え、 操作し、更新することができます。 mSQL はビューやネストされた問合せのようなリレーショナル能力をサポートしません。 ANSI 仕様で定義されたすべてのリレーショナル操作をサポートしてはいませんが、 複数のテーブル間を「結び付ける」能力を提供します。

本文中の、定義と例では大字文で mSQL キーワードを書きます。 しかし実際のクエリーでは、このような制限はありません。



Create 文

CREATE 文は、mSQL 2 で、CREATE TABLE と INDEX と SEQUENCE がサポートされました。 これはビューのような他の定義を作るために使うことはできません。 CREATE 文の 3 つの正しい構文は以下の通りです。


CREATE TABLE table_name (
col_name col_type [ not null ]
[ , col_name col_type [ not null ] ]**
)


CREATE [ UNIQUE ] INDEX index_name ON table_name (
field_name
[ , field_name ] **
)


CREATE SEQUENCE ON table_name [ STEP step_val ] [ VALUE initial_val ]


テーブルを作る例は以下の通りです。


CREATE TABLE emp_details (
first_name char(15) not null,
last_name char(15) not null,
comment text(50),
dept char(20),
emp_id int
)


有効なデータ型:

char (len) 文字列値(または、その他の 8 ビットデータ)
text (len) 文字列値(または、その他の 8 ビットデータ) 指定される長さは、 データの予想される平均の長さを示すために使われます。 指定の長さより長いデータは、 データテーブルと、外部のオーバーフローバッファに分けられます。

Note : text フィールドは char フィールドより遅く、 インデックスを使うこともできませんし、 LIKE による比較もできません。

int 符号付き整数値
real 10 進数あるいは指数部付表記リアル値



例で示したテーブル構造は、 インデックスを作ることで大いに恩恵を受けることができます。 emp_id フィールドは、 従業員を識別するために使われるユニークな値であると想定されます。 このようなフィールドは通常、プライマリキーと定義されます。 同じ結果はインデックスで達せられますが、 mSQL 2.0 では、 テーブル作成文でプライマリキーを作る支持をなくしました。 同様に、一般的なクエリーが、 名字と名前の組み合わせに基づいて従業員にアクセスするかもしれません。 複合インデックス(すなわち、2 つ以上のフィールドから作られる)は、 パフォーマンスを改善します。 私たちは以下のようにインデックスを作りました。


CREATE UNIQUE INDEX idx1 ON emp_details (emp_id)
CREATE INDEX idx2 ON emp_details (first_name, last_name)


これらのインデックスは、WHERE 文でそれらのフィールドを使うクエリーがデータベースエンジンに送られる時に、 常に、自動的に使われます。 ユーザはインデックスがパフォーマンスを上げるために使われる事を指示するために、 クエリーで特別な値を指定する必要はありません。


シーケンスは、 mSQL サーバによって数列を管理する仕組みを提供します。 これは(次の数列値を得るような)原始的な作業を考慮しています。 そして、クライアントアプリケーションで、 これらのオペレーションを行うことで関連づけられた関連を取り除きます。 数列はテーブルと結び付けられます。 そしてテーブルは大抵 1 つの数列を含んでいるかも知れません。

シーケンスが作られると、シーケンスが定義されているテーブルから _seq システム変数を SELECT することによってアクセスすることができます。 例えば、

CREATE SEQUENCE ON test STEP 1 VALUE 5
SELECT _seq FROM test

上記の CREATE オペレーションは、 test というテーブルにシーケンスを定義し、 それは 5 の初期値を持ち、 アクセスされるたびに、1 ずつ増加します。 上記の SELECT は、5 という値を返すでしょう。 もし SELECT が再び発行されたら、6 の値が返されるでしょう。 _seq フィールドが test から SELECT される度に、 現在の値が返されます、その後シーケンス値が増加します。

STEP と VALUE オプションを使って、どんな数からでも始まり、 どんな値によってでも増加するか、または減少するシーケンスを作ることができます。 もし -5 のステップで定義されたなら、アクセスされる度に、 シーケンスの値は 5 ずつ減少するでしょう。



Drop 文

DROP 文は定義をデータベースから削除するために使われます。 DROP 文はテーブルをデータベースから削除するために最も一般に使われます、 しかし同じくいくつかの他の構成物を削除するためにも使うことができます。 2.0 では、インデックス、シーケンス、 テーブルの定義を削除するために使うことができます。 テーブルあるいはインデックスを DROP することは、 定義と同様、 その対象と結び付けられたデータが削除されることには注意するべきです。

DROP 文の構文は以下の通りです。

DROP TABLE table_name
DROP INDEX index_name FROM table_name
DROP SEQUENCE FROM table_name

例:

DROP TABLE emp_details
DROP INDEX idx1 FROM emp_details
DROP SEQUENCE FROM emp_details



Insert 文

ANSI SQL と異なり、INSERT でネストすることはできません (つまり、SELECT の結果を INSERT することはできません)。 もし、フィールド名を指定しない場合は、定義されたという命令になります。 − もしそうした場合は、すべてのフィールドのために値を指定する必要があります。


INSERT INTO table_name [ ( column [ , column ]** ) ]
VALUES (value [, value]** )
例:
INSERT INTO emp_details
(first_name, last_name, dept, salary)
VALUES (`David', `Hughes', `Development','12345')
INSERT INTO emp_details
VALUES (`David', `Hughes', `Development','12345')
与えられた値の数はカラムの数に合わなくてはなりません。



Select 文

mSQL によって提供される SELECT は、 標準 SQL 仕様によって定義されている特徴に若干に欠けます。 mSQL 2 の開発は現在継続しています。 そしてこの欠けている機能のいくらかが、 次のベータリリースで利用可能になるでしょう。 今現在、mSQL の SELECT は、以下の機能を提供しません。

以下はサポートしています。

mSQL の SELECT 文の構文の公式の定義は以下の通りです。
SELECT [table.]column [ , [table.]column ]**
FROM table [ = alias] [ , table [ = alias] ]**
[ WHERE [table.] column OPERATOR VALUE
[ AND | OR [table.]column OPERATOR VALUE]** ]
[ ORDER BY [table.]column [DESC] [, [table.]column [DESC] ]

OPERATOR には <, >, =, <=, >=, <>, LIKE, RLIKE, CLIKE が使用可能です。
VALUE はリテラル値あるいはカラム名です。

WHERE 句 は、ネスト条件で '(' ')' を含んでも良いです。 例えば、"where (age < 20 or age > 30) and sex = 'male'" .

単純な SELECT の例:
SELECT first_name, last_name FROM emp_details
WHERE dept = `finance'

last_name を昇順で、first_name を降順でソートした結果を得るためのクエリーは以下のようになります。

SELECT first_name, last_name FROM emp_details
WHERE dept = `finance'
ORDER BY last_name, first_name DESC

そして、SELECT の結果から、重複した行を取り除くするために、 DISTINCT 演算子を、以下のように使うことができます。

SELECT DISTINCT first_name, last_name FROM emp_details
WHERE dept = `finance'
ORDER BY last_name, first_name DESC

mSQL は、WHERE 句で使うための、3 つの正規表現演算子を提供します。 標準 SQL 構文では提供されない、 そして、UNIX プログラマ、あるいはユーザが慣れるであろう柔軟性を持った、 非常に極端に単純化された正規表現能力を用意しています。 mSQL は、「標準」 SQL 正規表現構文を、LIKE 演算子によってサポートします。 しかし、もしそれが必要になったら、同じくそれ以上の機能性を供給してください。 利用可能な正規表現演算子は以下の通りです。

Note : CLIKE と RLIKE は標準的な SQL ではありません。 もしあなたのアプリケーションにポートすることに決めるなら、 他の言語では利用可能ではないかも知れません。 しかしながら、それらは、mSQL の非常に便利で、強力な特徴です。

LIKE と CLIKE 演算子によってサポートされる正規表現構文は、 標準的な SQL の構文であり、以下に概説します。

`_'どんな単一文字にでもマッチします
`%'0 あるいは複数のどんな文字にでもマッチします
`\'特別な文字をエスケープします (例えば、`\%' は、% にマッチします。`\\' は \ にマッチします)
すべての他の文字は、これらと一致します

LIKE 演算子の例として、金融部門から、Hughes のように、 どんな文字でも「ughes」によって後に続いた名前であるレコードを、 誰でも検索することが可能です。 実行すべきクエリーは以下の通りです。

SELECT first_name, last_name FROM emp_details
WHERE dept = `finance' and last_name like `_ughes'

RLIKE 演算子は、UNIX 標準正規表現構文によるアクセスを提供します。 UNIX 正規表現構文は SQL の LIKE 構文より、遥かに大きな機能性を提供します。 UNIX 正規表現構文は SQL の 正規表現 は(上で説明したように)、 "_" や "%" 文字を使いません。 RLIKE 演算子で利用可能な構文は以下の通りです

'.'どんな単一文字にでもマッチします
'^'正規表現の最初の文字として用いると、 この記号は文字列の先頭にマッチします。
'$'正規表現の最後の文字として用いると、 この記号は文字列の最後にマッチします。
'[ ]' 角カッコで単一文字グループをくくることによって、 その中の 1 つの文字にマッチします。 もし、']' という文字が、あなたがマッチさせたい文字のひとつだとしたら、 グループの最初の文字として指定します (つまり、'[]abc]' と指定すれば、']', 'a', 'b', 'c' のどれかの文字マッチします)。 'first-last' という構文で、グループの中で、文字の範囲を指定することができます (つまり、'[a-z0-9]' と指定すれば、すべての英小文字、 または数値にマッチします)。 もしグループの最初の文字が '^' なら、グループの中に含まれない、 すべての単一文字にマッチします。
'*' 何かの正規表現要素に続いて、'*' を指定すると、 0 以上のその正規表現要素にマッチします。

リレーショナルクエリー言語の能力は、 SELCT 操作でテーブル間を結び付ける時に、 はっきりと理解でき始めます。 2 つのテーブルを定義したとしましょう。 1 つはスタッフの詳細で、 もう 1 つはそれぞれのスタッフが取り組んでいるプロジェクトです。 そしてそれぞれのスタッフは、ユニークな社員番号を割り当てられています。 誰がどのプロジェクトに取り組んでいるのかについて、 ソートされた一覧を得るためのクエリーは以下の通りです。

SELECT emp_details.first_name, emp_details.last_name, project_details.project
FROM emp_details, project_details
WHERE emp_details.emp_id = project_details.emp_id
ORDER BY emp_details.last_name, emp_details.first_name

mSQL はクエリーで「結び付けられた」テーブルの数に制限はありません。 もし、従業員 ID と関係した情報を含んでいる 15 のテーブルがあれば、 ひとつのクエリーで、 それらのテーブルのそれぞれからデータを取り出すことができます。 結び付けることについて、注意すべき点の 1 つのキーポイントは、 テーブル名と、すべてのカラム名を与えなくてはならないということです。 mSQL は、 複数のテーブルでユニークな名前を持ったカラムの概念をサポートしていません。 だから、1 つの SELECT で 2 つ以上のテーブルにアクセスする場合は、 すべてのカラム名を与えることが必要になります。

mSQL は、テーブル自身を結び付けることができる、 テーブルエイリアスをサポートしています。 これは、あまり使用することがないように思われるかも知れません。 しかし、もしひとつのテーブルの中にお互いに関係をもったレコードがあるなら、 それは非常に強力な特徴なのです。 このようなテーブルの例は、親の名前を含んだ、人々のリストです。 そのようなテーブルは、親子関係を持った複数のレコードであるでしょう。 テーブルでどんな祖父母でも見つけだすことができる、 テーブルエイリアスは以下のように使います。

SELECT t1.parent, t2.child from parent_data=t1, parent_data=t2
where t1.child = t2.parent

テーブルエイリアス t1 と t2 は共に(この場合 parent_data に) 同じテーブルを指しています。 そして、正確に同じデータを含んでいる 2 つの異なったテーブルとして取り扱われます。



Delete 文

SQL の DELETE は、1 つあるいはそれ以上のエントリーを、 データベーステーブルから削除するために使われます。 テーブルから削除するレコードを選ぶ方法は、 SELECT 文で使われる WHERE の構文と同じに基づいています。 mSQL の DELETE 文の構文は以下の通りです。

DELETE FROM table_name
WHERE column OPERATOR value
[ AND | OR column OPERATOR value ]**

OPERATOR には <, >, =, <=, >=, <>, LIKE, RLIKE, CLIKE が使用可能です。
例:
DELETE FROM emp_details WHERE emp_id = 12345



Update 文

SQL の UPDATE 文は、 すでにデータベースにあるデータを修正するために使われます。 この操作は、WHERE の構文によって、 1 つあるいはそれ以上のレコードを指定して実行されます。 WHERE でマッチしたレコードの、どのフィールドの値でも更新できます。 mSQL の UPDATE 文のオペレーションには、 カラム名を更新値として用いることができない (すなわち、1 つのフィールドの値を、 もう 1 つのフィールドの現行値にセットすることができない) という点で、制限があります。 更新値としてリテラル値だけしか指定できません。 mSQL でサポートされている構文は以下の通りです。
UPDATE table_name SET column=value [ , column=value ]**
WHERE column OPERATOR value
[ AND | OR column OPERATOR value ]**

OPERATOR には <, >, =, <=, >=, <>, LIKE, RLIKE, CLIKE が使用可能です。

例:
UPDATE emp_details SET salary=30000 WHERE emp_id = 1234




Copyright © 1996 Hughes Technologies Pty Ltd.
訳:宮前 竜也