SQL ステートメントのコマンドリファレンス 
本章では、SQL コマンドをアルファベット順に詳細に説明および例示したオライリー・ジャパン発行の『SQL クイックリファレンス』の主な内容について説明します。各コマンドと関数は、本マニュアルで対象としている SQL Server、MySQL、Oracle、および PostgreSQL の製品固有の 4 つの SQL 言語に対して、基本表内で "対応 (S)"、"変則対応 (SWV)"、"制限付き対応 (SWL)"、または "未対応 (NS)" にそれぞれ分類されています。SQL99 標準、各ベンダーのアプリケーションの順に簡潔に漏れなく説明し、例およびサンプルコードを示します。
ALTER PROCEDURE 

ALTER PROCEDURE ステートメントは、既存のストアドプロシージャーを変更できます。変更の種類と程度はベンダーごとに大きく異なります。

 

SQL Server では、このステートメントは、CREATE PROCEDURE ステートメントで以前に作成したプロシージャーを、権限を変更せずに、また、従属するストアドプロシージャーやトリガーに影響を及ぼさずに変更します。

 

Oracle のこのコマンドは、単に PL/SQL ストアドプロシージャーを再コンパイルしますが、コードの変更はできません。代わりに、同じ機能を実現するには、Oracle コマンドの CREATE OR REPLACE PROCEDURE を使用します。

 
ベンダーコマンド
SQL Server変則対応
MySQL未対応
Oracle変則対応
PostgreSQL未対応
 
SQL99 の構文および説明
 
ALTER PROCEDURE procedure_name {CASCADE | RESTRICT}
[LANGUAGE | PARAMETER STYLE | <SQL data access> | <null clause behavior> | DYNAMIC RESULT SETS | NAME]
[parameter datatype [,...n]
 

CREATE PROCEDURE の説明にあるように、言語 (LANGUAGE)、パラメータスタイル (PARAMETER STYLE)、SQL データアクセスメソッド (NO SQLCONTAINS SQL など)、NULL 句の動作 (CALL ON NULL INPUT など)、動的結果セット (DYNAMIC RESULT SET)、およびプロシージャーの名前 (NAME) はすべて変更できます。

 

ALTER PROCEDURE コマンドは、入力パラメータの数や型の変更にも使用できます。

 
Microsoft SQL Server の構文およびバリエーション
 
ALTER PROC[EDURE] procedure_name [;number]
[ {@parameter datatype } [VARYING] [= default] [OUTPUT] ][,...n]
[WITH { RECOMPILE | ENCRYPTION  | RECOMPILE , ENCRYPTION } ]
[FOR REPLICATION]
AS
T-SQL Block
 

SQL Server では、このコマンドは、以前に作成したストアドプロシージャー (procedure_name) の任意の既存パラメータを変更できます。つまり、このコマンドのみで、DROP PROCEDURE ステートメントに続けて新たな CREATE PROCEDURE ステートメントを発行する場合と同じことができます。ストアドプロシージャーに対する権限や許可を再構築する必要はありません。構文の詳細については、CREATE PROCEDURE コマンドの項を参照してください。このコマンドを SQL Server で実行できるのは、ストアドプロシージャーの所有者、または db_owner および ddl_admin に固有のデータベースロールのメンバーです。

 
Oracle の構文およびバリエーション
 
ALTER PROCEDURE [user.]procedure_name COMPILE [DEBUG];
 

Oracle では、コンパイルするプロシージャーまたはパッケージの名前 ([user.]procedure_name) を指定する必要があります。COMPILE キーワードは必須です。COMPILE [DEBUG] オプションを指定すると、PL/SQL 情報が再生成されます。このコマンドを実行できるのは、ストアドプロシージャーの所有者か、ALTER ANY PROCEDURE を実行する特別な権限の所有者のみです。

 
 

Microsoft SQL Server を使用したこの例では、一意の CHAR(22) 出力文字列を生成する get_next_nbr というプロシージャーを作成します。次に、一意の INT 出力値を取得するようにプロシージャーを変更する際に、ALTER PROCEDURE を使用してストアドプロシージャーを再定義します。

 
-- A Microsoft SQL Server stored procedure
CREATE PROCEDURE get_next_nbr
   @next_nbr CHAR(22) OUTPUT
AS
BEGIN
  DECLARE @random_nbr INT
  SELECT @random_nbr = RAND(  ) * 1000000

SELECT @next_nbr =
  RIGHT('000000' + CAST(ROUND(RAND(@random_nbr)*1000000,0))AS CHAR(6), 6) +
  RIGHT('0000' + CAST(DATEPART (yy, GETDATE(  ) ) AS CHAR(4)), 2) +
  RIGHT('000'  + CAST(DATEPART (dy, GETDATE(  ) ) AS CHAR(3)), 3) +
  RIGHT('00'   + CAST(DATEPART (hh, GETDATE(  ) ) AS CHAR(2)), 2) +
  RIGHT('00'   + CAST(DATEPART (mi, GETDATE(  ) ) AS CHAR(2)), 2) +
  RIGHT('00'   + CAST(DATEPART (ss, GETDATE(  ) ) AS CHAR(2)), 2) +
  RIGHT('000'  + CAST(DATEPART (ms, GETDATE(  ) ) AS CHAR(3)), 3)
END
GO

ALTER PROCEDURE get_next_nbr
   @next_nbr INT OUTPUT
AS
BEGIN
  DECLARE @convert_to_nbr CHAR(22)
  DECLARE @random_nbr INT
  SELECT  @random_nbr = RAND(  ) * 1000000

SELECT @convert_to_nbr =
  RIGHT('000000' + CAST(ROUND(RAND(@random_nbr)*1000000,0))AS CHAR(6), 6) +
  RIGHT('0000' + CAST(DATEPART (yy, GETDATE(  ) ) AS CHAR(4)), 2) +
  RIGHT('000'  + CAST(DATEPART (dy, GETDATE(  ) ) AS CHAR(3)), 3) +
  RIGHT('00'   + CAST(DATEPART (hh, GETDATE(  ) ) AS CHAR(2)), 2) +
  RIGHT('00'   + CAST(DATEPART (mi, GETDATE(  ) ) AS CHAR(2)), 2) +
  RIGHT('00'   + CAST(DATEPART (ss, GETDATE(  ) ) AS CHAR(2)), 2) +
  RIGHT('000'  + CAST(DATEPART (ms, GETDATE(  ) ) AS CHAR(3)), 3)

SELECT @next_nbr = CAST(@convert_to_nbr AS INT)

END
GO
 
ALTER TABLE 

ALTER TABLE ステートメントは、テーブルを削除したりテーブルの既存の権限を変更することなく、既存のテーブルを変更できます。このステートメントを使用すると、既存のテーブルに対する増分変更を簡単に行えます。

 

Oracle と Microsoft SQL Server では、このコマンドをサポートしていますが、それぞれ異なる物理ファイルの割り当て方法を実現するため、いくつかのバリエーションがあります。

 
ベンダーコマンド
SQL Server変則対応
MySQL制限付き対応
Oracle変則対応
PostgreSQL変則対応
 
SQL99 の構文および説明
 
ALTER TABLE table_name
[ADD [COLUMN] column_name datatype attributes]
| [ALTER [COLUMN] column_name SET DEFAULT default_value]
| [ALTER [COLUMN] column_name DROP DEFAULT]
| [ALTER [COLUMN] column_name ADD SCOPE table_name
| [ALTER [COLUMN] column_name DROP SCOPE {RESTRICT | CASCADE}]
| [DROP [COLUMN] column_name {RESTRICT | CASCADE}]
| [ADD table_constraint_name]
| [DROP CONSTRAINT table_constraint_name {RESTRICT | CASCADE}]
 

SQL99 の ALTER TABLE ステートメントは、既存のテーブルに対して、多数の役立つ変更を行えます。この多機能なコマンドにより、列の追加 (ADD COLUMN) やテーブル制約の追加、初期設定値 (DEFAULT) の追加や削除、ユーザー定義の型を参照するように設定されている列に対する効力範囲 (SCOPE) の追加や削除、および列やテーブル制約の削除 (DROP) を行えます。DROP RESTRICT を指定すると、他のデータベースオブジェクトが、指定した列またはテーブル制約に依存する場合、ホスト DBMS によってコマンドが中止されます。DROP CASCADE を指定すると、指定した列またはテーブル制約に依存するあらゆるデータベースオブジェクトはホスト DBMS によって削除されます。これらのコマンド要素の詳細については、CREATE TABLE ステートメントの項を参照してください。

 
Microsoft SQL Server の構文およびバリエーション
 
ALTER TABLE table_name
[ALTER COLUMN column_name new_data_type attributes {ADD | DROP}
   ROWGUIDCOL]
| [ADD [COLUMN] column_name datatype attributes][,...n]
| [WITH CHECK | WITH NOCHECK] ADD table_constraint][,...n]
| [DROP { [ CONSTRAINT ] constraint_name | COLUMN column_name }] [,...n]
| [{ CHECK | NOCHECK } CONSTRAINT { ALL | constraint_name [,...n] }]
| [{ ENABLE | DISABLE } TRIGGER { ALL | trigger_name [,...n] }]
 

Microsoft SQL Server は、ALTER TABLE の実装において多くの機能を提供しています。ALTER COLUMN を指定すると、既存の列のデータタイプ、NULL の許容、識別関数などを変更できます。ADD を指定すると、新しい列、計算列、または制約をテーブルの最後に追加できます。現時点では、テーブルの最後以外の場所に列を挿入する手段はありません。COLUMN はわかりやすくするために提供されていますが、省略可能です。新しい列は、すべての制約、初期設定値および照合順序を含め、CREATE TABLE ステートメントと同じ方法で定義する必要があります。

 

WITH CHECK および WITH NOCHECK 句では、新しく追加した制約やキーでテーブル内のデータを検証するかどうかを指定します。WITH NOCHECK で追加する制約は、クエリオプティマイザによって考慮されません。このような制約はすべて ALTER TABLE table_name CHECK CONSTRAINT ALL を指定して有効化されるまで無視されます。制約は、DROP CONSTRAINT (CONSTRAINT キーワードは省略可) で削除でき、CHECK CONSTRAINT および NOCHECK CONSTRAINT で個々に有効化または無効化できます。

 

同様に、テーブルの指定トリガーは、ENABLE TRIGGER および DISABLE TRIGGER 句で有効化または無効化できます。テーブルのすべてのトリガーを有効化または無効化するには、ALTER TABLE employee DISABLE TRIGGER ALL のように、テーブル名を指定してキーワード ALL を指定します。

 
MySQL の構文およびバリエーション
 
ALTER [IGNORE] TABLE table_name
[ADD [COLUMN] column_name datatype attributes ]
   [FIRST | AFTER column_name]] [,...n]
| [ADD INDEX [index_name] (index_col_name,...)] [,...n]
| [ADD PRIMARY KEY (index_col_name,...)] [,...n]
| [ADD UNIQUE [index_name] (index_col_name,...)] [,...n]
| [ALTER [COLUMN] column_name {SET DEFAULT literal | DROP DEFAULT}] [,...n]
| [CHANGE [COLUMN] old_col_name create_definition] [,...n]
| [MODIFY [COLUMN] column_name datatype attributes] [,...n]
| [DROP [COLUMN] column_name] [,...n]
| [DROP PRIMARY KEY] [,...n]
| [DROP INDEX index_name] [,...n]
| [RENAME [AS] new_tbl_name] [,...n]
| [table_options]
 

指定可能な列属性およびテーブル制約の詳細については、CREATE TABLE ステートメントの項を参照してください。

 

IGNORE オプションを指定すると、一意キーを新たに定義する際に重複行を削除します。IGNORE を指定しないと、一意キー列に重複レコードが存在した場合、処理が中断されます。

 

FIRST オプションは、新しい列 (column_name) をテーブルの最初の列として追加する際に使用します。AFTER column_name を指定すると、column_name で指定したテーブル内の列の後に新しい列を追加します。

 

さらに MySQL では、ALTER TABLE ステートメントに柔軟性を与えています。ユーザーは、単一の ALTER TABLE ステートメント内に、ADDALTERDROP、および CHANGE 句を複数指定できます。ただし、CHANGE column_name および DROP INDEX 句は MySQL 独自の拡張で、SQL99 にはありません。MySQL では、Oracle の拡張 MODIFY column_name にも対応しています。ALTER COLUMN 句を指定すると、新しい初期設定値 (literal) を列 (column_name) に設定したり削除したりすることができます。

 

テーブルの名前は、RENAME AS を使用して変更でき、列の名前は、CHANGE で変更できます。たとえば、次のコードではテーブルと列の両方の名前を変更します。

 
ALTER TABLE employee RENAME AS emp;
ALTER TABLE employee CHANGE employee_ssn emp_ssn INTEGER;
 

MySQL では、列の一部 (列の最初の 10 文字など) に対してインデックスを作成できるため、そのインデックスの長さより短い列の作成には、CHANGEMODIFY コマンドを使用できません。DROP COLUMN を使用すると、指定した列は、テーブルおよびその列で作成されたすべてのインデックスから削除されます。

 

DROP PRIMARY KEY を指定したときに、テーブルに主キーが存在しなくても自動的に失敗にはなりません。代わりに、テーブルの最初の一意インデックスが削除されます。

 

MySQL では、データを損失することなく、既存列のデータタイプを再定義できます。ただし、列に含まれている値は、新しく定義するデータタイプに適合する必要があります。たとえば、日付型の列は文字データタイプに再定義できますが、文字データタイプは整数型に再定義できません。次に例を示します。

 
ALTER TABLE mytable MODIFY mycolumn LONGTEXT
 

MySQL では、FOREIGN KEYCHECK、および REFERENCES 句を指定できますが、これらは意味を持ちません。これらの句を含むコマンドを発行できますが、これらの句には効力がありません。これらの句は、主に移植時の互換性を保つために用意されています。

 
Oracle の構文およびバリエーション
 
ALTER TABLE [owner_name.]table_name
[ADD column_name datatype attributes]
| [MODIFY {column_name datatype
   | column_constraint
   | physical_storage_attributes [LOGGING | NOLOGGING]
   | nested_table_attributes}]
| [MODIFY CONSTRAINT {constraint_name {constraint_state}
   | drop_constraint_clause
   | drop_column_clause
   | [ALLOCATE | DEALLOCATE extent_clause]
   | [CACHE | NOCACHE]
   | [LOGGING | NOLOGGING]
   | [MONITORING | NOMONITORING] ]
| [DROP {[COLUMN] column_name | constraint_name}]
| [ALLOCATE EXTENT details]
| [DEALLOCATE UNUSED details]
| [RENAME TO new_table_name]
| [OVERFLOW physical_storage_attributes]
| [ADD OVERFLOW physical_storage_attributes]
| [{ADD | DROP | MODIFY | MOVE | TRUNCATE | SPLIT | EXCHANGE | MODIFY}
   PARTITION partition_details]
 

Oracle の ALTER TABLE ステートメントには、過剰な使用負荷を処理するためのデータエクステント処理、オーバーフローエクステント処理、テーブルのパーティショニングなど、物理記憶域の制御およびテーブル操作のための強力な機能が多数用意されています。上記の column_constraintphysical_storage_attributesnested_table_attributes などの行で使用可能な構文については、Oracle の CREATE TABLE の実装を確認してください。

 

このコマンドは、ADD を使用して列や制約を新たに追加でき、また MODIFY および DROP を使用して既存の列や制約を変更および削除できます。新しい列が追加される際、テーブルに行がない場合を除き、その列は NULL として定義されます。MODIFY キーワードを指定すると、以前に作成したテーブルの属性を変更できます。MODIFY CONSTRAINT を指定すると、LOGGINGCACHEMONITOR を有効にするかどうか、および、記憶域エクステントを ALLOCATEDEALLOCATE で割り当てるかどうかなど、テーブルの制約を削除または変更できます。また、テーブルの制約を有効化または無効化するには、ENABLE および DISABLE キーワードを使用します。

 

Oracle の ALTER TABLE は、高度な設定が可能ですが複雑です。コマンドの従属句の詳細については、CREATE TABLE ステートメントの項を参照してください。

 

次のコードでは、Oracle のテーブルに、列および一意制約を新たに追加します。

 
ALTER TABLE titles
ADD subtitle VARCHAR2(32) NULL
CONSTRAINT unq_subtitle UNIQUE;
 

外部キー制約をテーブルに追加する際は、テーブル内のすべての既存データがその制約に適合するかどうかが DBMS によって確認されます。適合しない場合、ALTER TABLE は失敗します。

 

SELECT * を使用するすべてのアプリケーションでは、計画外であったとしても、新しい列が返されます。一方、ストアドプロシージャーのようなプリコンパイル済みのオブジェクトは、新しい列を返しません。

 

また、Oracle では、ADDMODIFY などの複数のアクションを、複数の列に対して実行できます。アクションはかっこで囲みます。たとえば、次のコマンドでは、単一のステートメントでテーブルに複数の列を追加します。

 
ALTER TABLE titles
ADD (subtitles VARCHAR2(32) NULL,
   year_of_copyright INT,
   date_of_origin DATE);
 
PostgreSQL の構文およびバリエーション
 
ALTER TABLE table [*]
[ADD [COLUMN] column_name datatype attributes]
| [ALTER [COLUMN] column_name {SET DEFAULT value | DROP DEFAULT}]
| [RENAME [COLUMN] column_name TO new_column_name]
| [RENAME TO new_table_name]
 

PostgreSQL の ALTER TABLE の実装では、列 (column_name) の追加に ADD キーワードを使用します。既存の列には、ALTER COLUMN . . . SET DEFAULT を使用して新しい初期設定値 (value) を設定でき、一方、ALTER COLUMN . . . DROP DEFAULT を使用すると、列ベースで初期設定値を完全に削除できます。また、ALTER 句を使用して新しい初期設定値を列に追加できますが、その値が設定されるのは新しく挿入された行のみです。RENAME を指定すると、既存の列およびテーブルの名前を、新しい列名 (new_column_name) やテーブル名 (new_table_name) に変更できます。

 
ALTER TRIGGER  

ALTER TRIGGER ステートメントは、権限や従属関係を変更せずに既存のトリガー定義を変更します。

 
ベンダーコマンド
SQL Server変則対応
MySQL未対応
Oracle変則対応
PostgreSQL未対応
 
SQL99 の構文および説明
 

現時点では、このコマンドの SQL99 標準はありません。

 
Microsoft SQL Server の構文およびバリエーション
 
ALTER TRIGGER trigger_name
ON {table_name | view_name}
[WITH ENCRYPTION]
{FOR | AFTER | INSTEAD OF} {[DELETE] [,] [INSERT] [,] [UPDATE]}
[WITH APPEND]
[NOT FOR REPLICATION]
AS
  T-SQL_block
| [FOR { [INSERT] [,] [UPDATE] }
[NOT FOR REPLICATION]
AS

  { IF UPDATE(column) [{AND | OR} UPDATE(column)] [...n]
    |
    IF (COLUMNS_UPDATED(  ) {bitwise_operator} updated_bitmask)
    { comparison_operator} column_bitmask [...n] }
    T-SQL_block ] } ]
 

Microsoft SQL Server では、FOR | AFTER | INSTEAD OF { [DELETE] [,] [UPDATE] [,][INSERT] } | { [INSERT] [,] [UPDATE] } を指定して、コマンドの影響を受けるデータ変更ステートメントトリガーを記述できます。これらのオプションのうち最低 1 つを指定する必要がありますが、コンマで区切ることによって、どのように組み合わせることもできます。FOR および AFTER オプションは基本的に同じもので、指定するとデータ操作処理の完了後にトリガーのコードが実行されます。INSTEAD OF キー句を指定すると、データ操作処理の代わりにトリガーのコードが実行されます。

 

WITH APPEND 句を指定すると、指定タイプの追加トリガーが基本テーブルに追加されます。このオプションは、FOR トリガーでのみ使用できます。NOT FOR REPLICATION キー句を指定すると、sqlrepl などのレプリケーションログインによるアクションの場合、トリガーは実行されません。IF UPDATE (column) 句を指定すると、指定列で INSERT または UPDATE アクションが検査される (DELETE アクションは検査されない) ので、カーソルを使用した行ベースの操作時に非常に便利です。{AND | OR} 演算子を使用すると、同じ句に含まれる別の列を検査できます。IF (COLUMNS_UPDATED( )) を使用すると、指定した列が INSERT または UPDATE トリガーによって影響を受けたかどうかを調べられます。結果は、ビットごとの演算子として返されます。

 
Oracle の構文およびバリエーション
 
ALTER TRIGGER [user.]trigger_name [ENABLE | DISABLE | COMPILE [DEBUG] ];
 

Oracle のこのコマンドでは、トリガーの基底コードを完全に変更できません (ただし、Oracle の CREATE OR REPLACE TRIGGER の実装で同じ機能が実行できます)。Oracle の ALTER TRIGGER は、トリガーを有効化、無効化、または再コンパイルできます。COMPILE [DEBUG] オプションを指定すると、PL/SQL 情報が再生成されます。

 

Oracle では、 トリガーはテーブルに対してのみ使用できます (ただし、INSTEAD OF トリガーはビューに対しても使用可)。Microsoft SQL Server では、トリガーをテーブルおよび更新可能なビューに対して使用できます。

 
ALTER VIEW 

現時点では、SQL99 標準に ALTER VIEW はありませんが、このコマンドをサポートする各主要ベンダーのアプリケーション間で動作が異なることに注意する必要があります。Oracle では、このコマンドはビューの再コンパイルに使用されます。Microsoft SQL Server では、このコマンドを使用して、従属するすべてのストアドプロシージャー、トリガーまたは権限を変更せずにビューを変更できます。

 
ベンダーコマンド
SQL Server変則対応
MySQL未対応
Oracle変則対応
PostgreSQL未対応
 
SQL99 の構文および説明
 

現時点では、このコマンドの SQL99 標準はありません。

 
Microsoft SQL Server の構文およびバリエーション
 
ALTER VIEW view_name [(column [,...n])]
[WITH {ENCRYPTION | SCHEMABINDING | VIEW_METADATA]
AS
select_statement
[WITH CHECK OPTION]
 

CREATE VIEW ステートメントと同様に、ALTER VIEW を使用すると、ビュー (view_name) で列の名前付けに使用される列エイリアス (column [,n])、およびビューの中心コンポーネントの SELECT ステートメント全体 (select_statement) を指定できます。

 

ALTER VIEW ステートメントのその他の句については、CREATE VIEW ステートメントの項で説明しています。

 

Microsoft SQL Server では、コマンドの実行後に列名が同じである場合のみ、列の権限が維持されます。ENCRYPTION キーワードを使用すると、SQL Server の syscomments システムテーブル内のビューコードを暗号化できます。CHECK OPTION キーワードを指定すると、ビューに対して実行したすべてのデータ変更が、ビューを定義している select_statement の基準に強制的に準拠されます。これらのオプションのいずれかが以前にビューに定義されていた場合、これらのオプションは ALTER VIEW ステートメントを使用して有効化する必要があります。

 
Oracle の構文およびバリエーション
 
ALTER VIEW [user.]view_name COMPILE
 

Oracle の ALTER VIEW ステートメントは、ビューを再コンパイルします。このコマンドは、基本テーブルを変更した後にビューを有効化するのに便利です。ビューは、基本テーブルが変更されても再コンパイルされない場合は無効となります。

 
 

この SQL Server の例では、カリフォルニア (CA) 出身の作家を格納する california_authors というビューを作成します。次に、ALTER VIEW を使用して、そのビューを拡張および置換します。

 
CREATE VIEW california_authors
AS
SELECT au_lname, au_fname, city, state
FROM authors
WHERE state = 'CA'
WITH CHECK OPTION
GO

ALTER VIEW california_authors
AS
SELECT au_fname, au_lname, address, city, state, zip
FROM pubs..authors
WHERE state = "CA"
GO
 
CALL  

CALL ステートメントはストアドプロシージャーを呼び出します。

 
ベンダーコマンド
SQL Server未対応
MySQL未対応
Oracle対応
PostgreSQL対応
 
SQL99 の構文および説明
 
CALL procedure_name [(parameter [,...n] )]
 

CALL ステートメントを使用すると、ストアドプロシージャーの呼び出しを簡単に行えます。呼び出すには、ストアドプロシージャーの名前 (procedure_name) を指定し、ストアドプロシージャーで使用される任意のパラメータ (parameter [,n]) をかっこで囲んで指定するだけです。ストアドプロシージャーに OUT パラメータしかない場合やパラメータがない場合は、空のかっこを指定することもできます。

 

Microsoft SQL Server では、CALL ステートメントはサポートされていません。ただし、ほぼ同じ機能を、EXECUTE ステートメントを使用することによって実行できます。SQL Server のこの拡張機能の詳細については、ベンダーのマニュアルを参照してください。

 
Oracle の構文およびバリエーション
 
CALL [schema.][{type_name | package_name}.]procedure_name@dblink
[(parameter [,...n] )]
[INTO :variable_name [INDICATOR :indicator_name] ]
 

Oracle では、CALL ステートメントを使用して、スタンドアローンのストアドプロシージャー、関数、メソッドを呼び出せるだけでなく、あるタイプまたはパッケージに含まれるストアドプロシージャーや関数も呼び出せます。別のデータベース内のプロシージャーや関数を呼び出すには、dblink ステートメントを CALL ステートメントの一部として使用し、オブジェクトの場所を指定してそのデータベースを宣言します。dblink は以前に作成したデータベースリンクを参照しなければなりません。

 

呼び出すルーチンが関数の場合、Oracle では、INTO 句を指定する必要があります。反対に言えば、関数を呼び出す場合にのみ INTO 句を使用することができます。INTO 句には、関数によって返される値を格納する変数を指定する必要があります。最後に、関数がプリコンパイル済みの Pro*C/C++ ルーチンの場合、ホスト変数の状態を保持するために INDICATOR 句で指示子も指定できます。

 
 

次の例では、シンプルなストアドプロシージャーを作成し、そのプロシージャーを個別に呼び出します。

 
CREATE PROCEDURE update_employee_salary
(emp_id NUMBER, updated_salary NUMBER)
IS
BEGIN
  UPDATE employee SET salary = updated_salary WHERE employee_id =emp_id ;
END;

CALL update_employee_salary(1517, 95000);
 
CASE  

CASE 関数を使用すると、SELECT または UPDATE ステートメント内で条件分岐処理の IF-THEN-ELSE 機能を実行できます。この関数は条件リストを評価し、いくつかの候補値の中から 1 つの値を返します。

 
ベンダーコマンド
SQL Server対応
MySQL対応
Oracle未対応 (同様の機能については、ベンダーのマニュアルにある DECODE 関数の説明を参照してください)
PostgreSQL対応
 

CASE には、単純 CASE および検索 CASE の 2 つがあります。単純 CASE 式は、1 つの値 (input_value) を他の値のリストと比較し、最初に一致した値に関連する結果を返します。検索 CASE 式はいくつかの論理条件を分析し、最初に真となった条件に関連する結果を返します。

 
SQL99 の構文および説明
 
-- Simple comparison operation
CASE input_value
WHEN when_condition THEN resulting_value
[...n]
[ELSE else_result_value]
END

-- Boolean searched operation
CASE
WHEN Boolean_condition THEN resulting_value
[...n]
[ELSE else_result_expression]
END
 

単純 CASE 関数では、input_value の値が各 WHEN 句に対して評価されます。resulting_value は、input_value = when_condition が最初に TRUE となった場合に返されます。when_condition が TRUE として評価されない場合、else_result_value が返されます。else_result_value を指定しない場合、NULL が返されます。

 

より複雑なブール値検索処理では、各 WHEN 句に独自のブール値比較処理を設定する以外は、式の構造は単純比較処理と基本的に同じです。

 

どちらでも、複数の WHEN 句を使用できますが、ELSE 句の指定は 1 つのみです。

 
 

CASE 関数を使用して contract 列の表示をより明確にする単純比較処理の例を次に示します。

 
SELECT  au_fname,
        au_lname,
        CASE contract
            WHEN 1 THEN 'Yes'
            ELSE 'No'
        END 'contract'
FROM    authors
WHERE   state = 'CA'
 

次に SELECT ステートメント内に指定した複雑な検索 CASE 関数の例を示します。ここでは、年間の売上数の範囲ごとのタイトル数をレポートします。

 
SELECT CASE
           WHEN ytd_sales IS NULL  THEN 'Unknown'
           WHEN ytd_sales <=   200 THEN 'Not more than 200'
           WHEN ytd_sales <=  1000 THEN 'Between  201 and  1000'
           WHEN ytd_sales <=  5000 THEN 'Between 1001 and  5000'
           WHEN ytd_sales <= 10000 THEN 'Between 5001 and 10000'
           ELSE 'Over 10000'
       END 'YTD Sales',
       COUNT(*) 'Number of Titles'
FROM   titles
GROUP BY CASE
           WHEN ytd_sales IS NULL  THEN 'Unknown'
           WHEN ytd_sales <=   200 THEN 'Not more than 200'
           WHEN ytd_sales <=  1000 THEN 'Between  201 and  1000'
           WHEN ytd_sales <=  5000 THEN 'Between 1001 and  5000'
           WHEN ytd_sales <= 10000 THEN 'Between 5001 and 10000'
           ELSE 'Over 10000'
         END
ORDER BY MIN( ytd_sales )
 

次にこの結果を示します。

 
YTD Sales              Number of Titles
---------------------- ----------------
Unknown                2
Not more than 200      1
Between  201 and  1000 2
Between 1001 and  5000 9
Between 5001 and 10000 1
Over 10000             3
 

すべてのタイトルに割引を適用する UPDATE ステートメントの例を次に示します。以下に続く、より複雑なコマンドでは、パーソナルコンピュータ関連のすべてのタイトルに対して 25%、その他のタイトルに対して 10%、および会計年度内の売上が 10,000 ユニット以上のタイトルに対して 5% の割引を適用します。

 

次の UPDATE クエリーでは、価格調整に検索 CASE 式が使用されています。

 
UPDATE  titles
SET     price = price *
        CASE
            WHEN ytd_sales > 10000     THEN 0.95  -- 5% discount
            WHEN type = 'popular_comp' THEN 0.75  -- 25% discount
            ELSE 0.9                              -- 10% discount
        END
WHERE   pub_date IS NOT NULL
 

この UPDATE ステートメントでは、1 つのステートメントで 3 つの異なる更新処理が完了します。

 
CAST  

CAST コマンドは、1 つのデータタイプの式を別のデータタイプに明示的に変換します。

 
ベンダーコマンド
SQL Server対応
MySQL未対応
Oracle未対応
PostgreSQL対応
 
SQL99 の構文および説明
 
CAST(expression AS data_type[(length)])
 

CAST 関数は、列の値や変数などの任意の式を別の定義済みのデータタイプに変換します。データタイプの長さは、長さを持つ CHARVARCHAR などのデータタイプに対してオプションで指定できます。

 

DECIMAL 値から INTEGER 型への変換など、特定の変換では、値が丸められる場合があります。また、変換後の値を表すのに十分な領域が新しく指定したデータタイプにない場合は、エラーが発生する場合があります。

 
 

この例では、会計年度内の売上を CHAR 型として取得し、そのデータを文字列および本のタイトルの一部と連結します。例では、ytd_salesCHAR(5) に変換し、title の長さを短くし、結果を読みやすくします。

 
SELECT CAST(ytd_sales AS CHAR(5)) + "Copies sold of " + CAST(title AS
VARCHAR(30))
FROM titles
WHERE ytd_sales IS NOT NULL
  AND ytd_sales > 10000
ORDER BY ytd_sales DESC
 

次にこの結果を示します。

 
---------------------------------------------------
22246 Copies sold of The Gourmet Microwave
18722 Copies sold of You Can Combat Computer Stress
15096 Copies sold of Fifty Years in Buckingham Pala
 
CLOSE CURSOR 

CLOSE CURSOR コマンドは、DECLARE CURSOR ステートメントで作成したサーバーサイドカーソルを閉じます。MySQL では、サーバーサイドカーソルをサポートしていませんが、広範な C プログラミング拡張はサポートしています。

 
ベンダーコマンド
SQL Server対応
MySQL未対応
Oracle対応
PostgreSQL対応
 
SQL99 の構文および説明
 
CLOSE { cursor_name }
 

cursor_name には、DECLARE CURSOR コマンドで作成したカーソルの名前を指定します。

 
 

次の Microsoft SQL Server の例では、カーソルを開き、すべての行を取得します。

 
DECLARE employee_cursor CURSOR FOR
  SELECT lname, fname
  FROM pubs.dbo.authors
  WHERE lname LIKE 'K%'

OPEN employee_cursor

FETCH NEXT FROM employee_cursor

WHILE @@FETCH_STATUS = 0
BEGIN
  FETCH NEXT FROM Employee_Cursor
END

CLOSE employee_cursor

DEALLOCATE employee_cursor
 

Microsoft SQL Server の DEALLOCATE ステートメントは、カーソルが使用していたリソースとデータ構造を解放しますが、Oracle、PostgreSQL、および MySQL ではこのステートメントを使用しません。

 
COMMIT TRANSACTION 

COMMIT TRANSATION ステートメントは、BEGIN で明示的に開いたトランザクション、または INSERTUPDATEDELETE ステートメントで暗黙的に開いたトランザクションを明示的に終了します。このコマンドを使用すると、データ操作処理を手動で完了できます。

 
ベンダーコマンド
SQL Server変則対応
MySQL未対応
Oracle対応
PostgreSQL対応
 
SQL99 の構文および説明
 
COMMIT [WORK]
 

COMMIT には、1 つまたはグループのデータ操作処理の終了以外にも、トランザクションの別の側面に対して興味深い効果があります。効果の 1 つ目は、開いている関連カーソルがすべて閉じられることです。2 つ目の効果として、ON COMMIT DELETE ROWS で指定した任意の一時テーブルのデータが消去されます。3 つ目として、トランザクションによって行われたすべてのロックが解放されます。最後に、すべての遅延制約がチェックされます。遅延制約に違反がある場合、トランザクションはロールバックされます。

 

SQL99 では、次のステートメントのいずれかを実行すると、トランザクションが暗黙的に開かれます。

 
  • ALTER
  • CLOSE
  • COMMIT AND CHAIN (SQL99 の新機能)
  • CREATE
  • DELETE
  • DROP
  • FETCH
  • FREE LOCATOR
  • GRANT
  • HOLD LOCATOR
  • INSERT
  • OPEN
  • RETURN
  • REVOKE
  • ROLLBACK AND CHAIN (SQL99 の新機能)
  • SELECT
  • START TRANSACTION (SQL99 の新機能)
  • UPDATE
 

SQL99 では、省略可能な新しい AND CHAIN キーワードが用意されています。このコマンドに対応しているベンダーはまだありません。この新しい構文を次に示します。

 
COMMIT [WORK] [AND [NO] CHAIN]
 

AND CHAIN オプションを指定すると、後に続くトランザクションが先行するトランザクションの一部であるかのように処理されます。実際は、2 つのトランザクションは別々の処理単位ですが、トランザクション隔離レベルなどの共通のトランザクション環境が共有されます。AND NO CHAIN オプションを指定すると、単に 1 つのトランザクションが終了されます。COMMIT コマンドは、COMMIT WORK AND NO CHAIN コマンドの機能と同じです。

 
Microsoft SQL Server の構文およびバリエーション
 
COMMIT [TRAN[SACTION] [transaction_name | @tran_name_variable] ]
|
COMMIT [WORK]
GO
 

Microsoft SQL Server では、特定の指定トランザクションを永続的なものにすることができます。COMMIT コマンドは、BEGIN TRAN コマンドとペアで使用する必要があります。COMMIT TRANSACTION の構文では、終了するトランザクション (transaction_name) を明示的に指定したり、トランザクション名を変数 (@tran_name_variable) に格納したりできます。不思議なことですが、SQL Server では、指定したトランザクションの名前にかかわらず、最後に開いたトランザクションのみがコミットされます。COMMIT WORK を使用する場合、トランザクション名またはトランザクション名を格納している変数は指定できません。

 

ただし、この構文は、名前付きのトリガーがネストする場合は紛らわしくなります。というのは、この構文は最も外側のトランザクションを閉じるからです。SQL Server のトランザクションは、@@TRANCOUNT グローバル変数の数値で識別されます。@@TRANCOUNT が 0 の場合のみ、すべてのトランザクションがコミットされます。

 
Oracle の構文およびバリエーション
 
COMMIT [WORK];
 

Oracle では指定トランザクションを特に認めていません (セーブポイントは使用可)。したがって、最後に COMMIT ステートメントが明示的または暗黙的に実行された時点から、単純にすべてのデータ操作処理が確定されます。Oracle では、WORK キーワードを使用できますが、常に省略可能です。

 
PostgreSQL の構文およびバリエーション
 
COMMIT [WORK | TRANSACTION];
 

PostgreSQL では、WORK および TRANSACTION キーワードは共に省略可能です。コマンドの効力は、どちらのキーワードを指定しても、または指定しなくても同じです。完了時には、コミットされたトランザクションはすべてディスクに書き込まれ、他のユーザーに表示されます。

 
 
INSERT INTO sales VALUES('7896','JR3435','Oct 28
1997',25,'Net
60','BU7832');

COMMIT WORK;
 
連結演算子 

SELECT の結果セット内で複数列のデータを連結して 1 つの列にする必要がある場合、DBMS でサポートされている連結記号を使用して連結できます。

 
ベンダーコマンド
SQL Server変則対応
MySQL変則対応
Oracle対応
PostgreSQL対応
 
例および説明
 
SELECT lname || ', ' || fname FROM customers WHERE cust_id = 41;
 

このコード例で示されているように、ANSI 規格の連結記号は、 2 重パイプ記号 (||) で、Oracle および PostgreSQL でサポートされています。

 

Microsoft SQL Server では、連結記号として プラス記号 (+) を使用します。

 

MySQL では、CONCAT(string1, numeric1, string2, numeric2 [,...n]) 関数を連結に使用します。

 
CONNECT 

CONNECT ステートメントは、DBMS や DBMS 内の指定データベースへの接続を確立します。

 
ベンダーコマンド
SQL Server制限付き対応
MySQL未対応
Oracle対応
PostgreSQL未対応
 
SQL99 の構文および説明
 
CONNECT [TO] DEFAULT
| {[server_specification] [AS connection_name] [USER user_name ] }
 

明示的に接続を切らずに、CONNECT ステートメントが呼び出された場合、古いセッションが停止し、新しいセッションがアクティブになります。通常、CONNECTDISCONNECT ステートメントを発行する間の期間が、セッションと呼ばれています。一般的に、ユーザーは明示的に起動したセッション期間に、DBMS 上のすべての処理を完了します。

 

Oracle のツールである SQL*Plus では、CONNECT コマンドの使用方法がいくぶん異なります。これは、ユーザーを特定のスキーマに接続するためです。

 

CONNECT TO DEFAULT ステートメントは、ベンダーごとに実装が異なるので、多少異なる結果を返します。ただし標準では、ユーザー認証および現行データベースがデフォルトのサーバーでデフォルトセッションを開始するコマンドです。

 

CONNECT TO DEFAULT とは対照的に、CONNECT TO server_name では、サーバーを指定できます。ここでは、明示的に指定したサーバーに接続します。さらに、AS で接続名を、USER でユーザー名を宣言できます。

 
Oracle の構文およびバリエーション
 
CONN[ECT] [[username/password] [AS [SYSOPER | SYSDBA] ] ]
 

CONNECT 句に特定のユーザー名 (username) を指定して、データベースに接続できます。または、AS SYSOPERAS SYSDBA などの特別な権限を使った接続を確立できます。別の接続が既に開かれている場合、CONNECT は開いているすべてのトランザクションをコミットし、現行のセッションを閉じて新しいセッションを開きます。

 

PostgreSQL では、CONNECT コマンドを明示的にサポートしていません。ただし、SPI (Server Programming Interface) において SPI_CONNECT ステートメントをサポートし、PG/tcl プログラミングパッケージにおいて PG_CONNECT ステートメントをサポートしています。

 
 

特定のユーザー ID を使用して接続するには、ユーザーまたは自動化プログラムは次のコマンドを発行します。

 
CONNECT TO USER pubs_admin
 

指定接続が必要な DBMS の場合、次の代替構文を使用します。

 
CONNECT TO USER pubs_admin AS pubs_administrative_session;
 

Microsoft SQL Server では、Embedded SQL (ESQL) でのみ CONNECT TO をサポートしています。

 
EXEC SQL CONNECT TO new_york.pubs USER pubs_admin
 
CREATE DATABASE 

実際は、SQL99 に CREATE DATABASE ステートメントは含まれていません。CREATE DATABASE に最も近い SQL99 のステートメントは、CREATE SCHEMA および CREATE CATALOG です。CREATE SCHEMA の詳細については後で説明します。ただし、SQL データベースを操作するにはこのコマンドは不可欠です。ほぼすべてのベンダーが、このコマンドまたはこのコマンドの変則バージョンをサポートしています。

 
ベンダーコマンド
SQL Server変則対応
MySQL対応
Oracle対応
PostgreSQL変則対応
 
SQL99 の構文および説明
 
CREATE database_name
 

この構文では、database_name が新たに作成するデータベースの識別子です。このコマンドは、指定した名前の空のデータベースを新たに作成します。ほとんどのベンダーでは、新しいデータベースを作るユーザーは、root、master、または system database の権限を持つことが要求されます。新しいデータベースを作成したら、そのデータベースにテーブル、ビュー、トリガーなどのデータベースオブジェクトを入れることができ、テーブルにはデータを格納できます。

 
Microsoft SQL Server の構文およびバリエーション
 

SQL Server および Oracle では、データベースは、事前に作成されたファイル構造内でインスタンス化されます。これらのファイルは、データベースシステムとオペレーティングシステムの仲介役として働きます。その結果、SQL Server 版と Oracle 版の CREATE DATABASE は、同様により高度化されています。

 

次に、Microsoft SQL Server の構文を示します。

 
CREATE DATABASE database_name
[ ON [PRIMARY]
[ <file> [,...n] ]
[, <file_group> [,...n] ]
]
[ LOG ON { <file> [,...n]} ]
[ FOR LOAD | FOR ATTACH ]
GO
 

この実装では、データベースの名前 (database_name) を指定できるだけでなく、データベースを格納する場所も指定できます。Oracle および SQL Server は共に、データベースのリポジトリとして機能するファイル (ディスク構造上に作成された事前定義領域) を使用します。データベースは、ファイル (file) やファイルグループ (file_group) に格納されます。また、SQL Server では、LOG ON 句を使用して、データベースとは別の場所にトランザクションログを格納できます。これらの機能によって、ディスク I/O を最適に制御するための高度なファイル計画が可能となります。

 

FOR LOAD 句を指定すると、データベースの作成後に、バックアップがデータベースに直ちに読み込まれ、最初の作成時間が短縮されます。FOR ATTACH 句を指定すると、DVD-ROM、CD-ROM、またはポータブルハードディスクなどの既存のオペレーティングシステムのファイル構造をデータベースにアタッチできます。

 
MySQL と PostgreSQL の構文およびバリエーション
 

MySQL の CREATE DATABASE は、基本的にデータベースオブジェクトを格納する新しいディレクトリを作成します。つまり、これらのベンダーでは、データベースの作成はファイルシステムディレクトリの作成とほぼ同じです。データベースはベンダーアプリケーションのメインディレクトリ下にディレクトリとして作成され、データベース内に新たに作成するすべてのオブジェクトはそのフォルダ内に格納されます。これは PostgreSQL でも同じですが、PostgreSQL では、WITH LOCATION オプションを使用して、データベースの場所を指定できます。

 
CREATE DATABASE name [ WITH LOCATION = 'dbpath' ];
 

たとえば、データベース sales_revenue/home/teddy/private_db ディレクトリに作成するには、次のように指定します。

 
CREATE DATABASE sales_revenue WITH LOCATION = '/home/teddy/private_db';
 
Oracle の構文およびバリエーション
 
CREATE DATABASE [database_name]
[CONTROLFILE REUSE]
[LOGFILE [GROUP1 integer] file1 integer [K | M] [,...n] [REUSE]]
   [MAXLOGFILES integer]
   [[MAXLOGMEMBERS] integer]
   [[MAXLOGHISTORY] integer]
[DATAFILE file1 [AUTOEXTEND [,...n] [ON | OFF]]
      [NEXT integer [K | M]]
      [MAXSIZE [UNLIMITED | integer [K | M]]
   [MAXDATAFILES integer]
   [,...n]]
[MAXINSTANCES integer]
[MAXDATAFILES integer]
[ARCHIVELOG | NOARCHIVELOG]
{CHARACTER SET charset}
{NATIONAL CHARACTER SET charset};
 

Oracle の CREATE DATABASE は非常に強力なコマンドであるため、経験のあるデータベース管理者のみが使用してください。あまり経験のないユーザーが使用すると、このコマンドによって、既存のデータベースを破損してしまう可能性があります。

 

Microsoft SQL Server と同様に Oracle でも、単なるデータベース名やデータベースファイルのパスの指定だけでなく、データベースファイル構造を扱う高度なレベルの操作性が提供されています。また、Oracle の環境に特有な INIT.ORA ファイルによって、データベースを作成および起動する際のデータベース名とその他の様々なオプションを指定します。INIT.ORA ファイルは常に使用し、このファイルに制御ファイルを指定する必要があります。そうしなければ、データベースは起動しません。

 

file1 [,...n] オプションを使用する場合、次のフォーマットでファイル名およびファイルサイズ (バイト、キロバイト、またはメガバイト単位) を指定できます。

 
'file_path_and_name' SIZE bytes [K | M] REUSE
 

[K | M] オプションを使用すると、ファイルのバイトサイズはそれぞれ、1024 または 1048576 で乗算されます。REUSE オプションを使用すると、ファイルが存在しない場合はファイルを作成し、存在する場合は再利用します。CONTROLFILE REUSE オプションを指定すると、制御ファイルが上書きされます。同様に、LOGFILE . . . REUSE を指定すると、ログファイルが上書きされます。

 

ログファイルをグループでリストする場合、通常は、かっこで囲みます。メンバーが 1 つのみのグループを作成する場合、かっこは必要ありませんが、そのような場合はあまりありません。ログファイルのリストをかっこで囲んだ例を次に示します。

 
CREATE DATABASE publications
LOGFILE ('/s01/oradata/loga01','/s01/oradata/loga02') SIZE 5M
DATAFILE
 

さらに、LOGFILE および DATAFILE オプションとサブオプションを指定すると、データベースの REDO ログファイルおよびデータベースファイルのサイズと拡張パターンを厳密に制御できます。MAXLOGFILES および MAXDATAFILES は、作成可能な REDO ログファイルとデータベースファイルの最大数をそれぞれ定義します。AUTOEXTEND が有効な場合、UNLIMITED に設定されていない限り、NEXT で指定したサイズずつ、MAXSIZE で指定したサイズまでデータファイルが拡張します。MAXLOGMEMBERS は、コピー可能な REDO ロググループの最大数を制御します。Oracle Parallel Server で使用する MAXLOGHISTORY を指定すると、適切な領域が制御ファイル内に記録されるように、アーカイブ REDO ログファイルの最大数が制御されます。

 

MAXINSTANCES パラメータは、作成したデータベースを同時にマウントできるインスタンスの最大数を設定します。ARCHIVELOGNOARCHIVELOG は、相互に排他的なオプションで、REDO ログの運用方法を定義します。ARCHIVELOG を指定すると、データは追加のアーカイブファイルに保存され、メディアのリカバリに使用できます。どちらのオプションを指定してもリカバリ可能ですが、NOARCHIVELOG (デフォルト) では通常、メディア障害をリカバリできません。CHARACTER SET は、オペレーティングシステムに依存し、格納されるデータの言語および文字セットを制御します。

 
CREATE FUNCTION 

CREATE FUNCTION ステートメントはユーザー定義関数 (UDF) を作成します。UDF は入力引数をとり、CAST( ) と同様に、1 つの値を返します。UDF は、他のシステム関数と同様にクエリー内部で呼び出すことができます。

 

SQL 関数およびベンダー間の個々の実装の詳細については、第 4 章を参照してください。

 
ベンダーコマンド
SQL Server変則対応
MySQL変則対応
Oracle変則対応
PostgreSQL変則対応
 

データベースプログラマーは CREATE FUNCTION ステートメントを使用して、ユーザー定義関数を作成できます。作成した関数は、INSERTUPDATE、および DELETE ステートメントの WHERE 句などのクエリーやデータ操作処理で呼び出すことができます。このステートメントの基本構文は次に示すとおりですが、ベンダーによる実装方法は大きく異なるので、本項ではこの後に、それぞれの実装方法を説明します。

 
SQL99 の構文および説明
 
CREATE FUNCTION function_name
[(parameter datatype attributes [,...n])]
RETURNS datatype

  [LANGUAGE {ADA | C | FORTRAN | MUMPS | PASCAL | PLI | SQL}]
  [PARAMETER STYLE {SQL | GENERAL}]
  [SPECIFIC specific_name]
  [DETERMINISTIC | NOT DETERMINISTIC]
  [NO SQL | CONTAINS SQL | READS SQL DATA | MODIFIES SQL DATA]
  [RETURNS NULL ON NULL INPUT | CALL ON NULL INPUT]
  [STATIC DISPATCH]

code block
 

SQL99 標準の CREATE FUNCTION ステートメントには、主なコンポーネントの他にも、あまり使用されないより高度なコンポーネントが用意されています。ほとんどの UDF では、ユーザーは、関数名、任意の入力パラメータ、および UDF が返す値のデータタイプを定義します。これらによって、コマンドの基本的な用法が決まります。

 

SQL99 標準では、さらに多くの指定が可能です。LANGUAGE 句を指定すると、関数を記述する言語 (PostgreSQL など) を宣言できます。PARAMETER STYLE 句を使用すると、典型的な SQL スタイル以外のパラメータスタイルを GENERAL キーワードで宣言できます。デフォルトは SQL です。SPECIFIC 宣言は、ユーザー定義型の関数名をさらに制限指定するために使用します。DETERMINISTIC または NOT DETERMINISTIC 句を指定すると、関数に同じ入力パラメータを与えた場合、常に同じ結果を返す (決定性である) かどうかを、ホスト DBMS に指示します。決定性の関数のみが制約内で使用できます。

 

SQL データアクセス句の NO SQL を指定すると、関数に SQL コードは含まれせんが、CONTAINS SQL では含まれます。READS SQL DATA を指定すると、関数で SELECT または FETCH ステートメントを使用でき、MODIFIES SQL DATA を指定すると、任意のデータ変更ステートメントを使用できます。デフォルトは CONTAINS SQL です。

 

NULL を処理できないホスト言語に対しては、RETURNS NULL ON NULL INPUT を宣言し、関数が NULL を処理した際に NULL を返すようにします。反対に、CALL ON NULL INPUT (デフォルト) では、NULL パラメータを通常どおりに処理し、結果が不定となります。

 

STATIC DISPATCH 句は、ユーザー定義型または ARRAYS 型を使用するパラメータを含む非 SQL 関数に対して使用します。

 
Microsoft SQL Server の構文およびバリエーション
 
CREATE FUNCTION [owner_name.]function_name
( [ {@parameter1 datatype [=default]} [,...n] ] )
RETURNS {datatype | TABLE]
[WITH {ENCRYPTION | SCHEMABINDING}]
AS <Transact-SQL body>
GO
 

SQL Server の関数は、TABLE データタイプを介して複数の値を返すことができます。TABLE データタイプは、付随する列リストがなく、単一の SELECT ステートメントで定義されている場合、インラインと見なされます。RETURN 句が TABLE データタイプを介して複数の値を返すときに、TABLE が列および列のデータタイプを定義している場合、この関数は複数ステートメントのテーブル値関数です。

 

SQL Server では、作成するユーザー定義関数にユーザー定義パラメータを宣言する必要があります。SQL Server の timestamp 以外のすべてのデータタイプがパラメータとしてサポートされています。関数は、timestamptextntextimage 以外の任意のデータタイプの値を返すことができます。インラインテーブル値が必要な場合、列リストを伴わない TABLE オプションを使用できます。

 

Microsoft SQL Server のユーザー定義関数は、SQL Server の他の多くのデータベースオブジェクトと同様、ENCRYPTION または SCHEMABINDING オプションを指定して作成できます。ENCRYPTION オプションを指定すると、関数のテキストを格納するシステム列テーブルが暗号化されるので、関数コードが無許可で参照されないようにできます。SCHEMABINDING オプションを指定すると、テーブルやビューなどの特定のデータベースオブジェクトに関数がバインドされます。バインドされたデータベースオブジェクトは、その関数が存在しているか、その関数に SCHEMABINDING オプションが指定されている限り、変更も削除もできません。

 

Transact-SQL のコード本体には、インライン関数用に単一の SELECT ステートメントを RETURN (SELECT . . . ) のフォーマットで指定するか、複数ステートメント操作用に一連の Transact-SQL ステートメントを指定します。BEGIN . . . END ブロック内に保持される Transact-SQL ステートメント本体は、データを恒久的には変更できず、その他の継続する副作用も発生させることはできません。このブロックの最後のステートメントには、単一のデータタイプの値または TABLE 値を返す無条件の RETURN ステートメントを指定する必要があります。

 

Transact-SQL ブロックには、@@CONNECTIONSGETDATE などの、異なる値を返すグローバル変数は使用できません。ただし、@@SERVERNAME などの、同じ結果値を返す変数は使用できます。コードはデータを恒久的に変更したり、その他の継続する副作用を発生させることができないため、その他にも多くの制限があります。たとえば、INSERTUPDATE、および DELETE ステートメントで変更できるのは、その関数にローカルな TABLE 変数のみです。

 

1 つの値を返すスカラー関数の例を次に示します。

 
CREATE FUNCTION metric_volume -- Input dimensions in centimeters.
   (@length decimal(4,1),
   @width decimal(4,1),
   @height decimal(4,1) )
RETURNS decimal(12,3) -- Cubic Centimeters.
AS BEGIN
      RETURN ( @length * @width * @height )
   END
GO
 

このユーザー定義関数は、その他の関数同様、クエリーや他の処理で利用できます。たとえば、すべての建設プロジェクト (housing_construction) から、容積が 300,000 立法メートル以上のプロジェクト名 (project_name) とその容積 (metric_volume) を検索するには次のように記述します。

 
SELECT project_name,
   metric_volume(construction_height,
      construction_length,
      construction_width)
FROM housing_construction
WHERE metric_volume(construction_height,
      construction_length,
      construction_width) >= 300000
GO
 

テーブルの値を返すユーザー定義関数は、結果セット値として使用したり、通常のテーブルと同じように、SELECT ステートメントの FROM 句内で使用したりします。FROM 句内では、通常のテーブル同様、テーブルエイリアス関数を割り当てることができます。次に例を示します。

 
SELECT co.order_id, co.order_price
FROM   construction_orders AS co,
       fn_construction_projects('Cancelled') AS fcp
WHERE  co.construction_id = fcp.construction_id
ORDER BY co.order_id
GO
 
MySQL の構文およびバリエーション
 
CREATE [AGGREGATE] FUNCTION function_name
RETURNS {STRING | REAL | INTEGER}
SONAME shared_program_library_name ;
 

MySQL の CREATE FUNCTIONAGGREGATE オプションを使用すると、SUM( ) および COUNT( ) などのようにユーザー定義関数を集計できます。戻り値の型は、文字データは STRING 型、浮動小数点数は REAL 型、整数は INTEGER 型を指定できます。

 

MySQL の CREATE FUNCTION の実装は、オペレーティングシステム上の手続きコードは、動的ロードに対応した C/C++ でなければならないため、他のベンダーと大きく異なります。C/C++ プログラムの指定には、shared_program_library_name オプションを使用します。関数は、MySQL サーバーに直接コンパイルして永続的に使用することも、動的な呼び出しプログラムとすることもできます。ユーザー定義関数は C/C++ プログラムとして書かれるため、本マニュアルではこの実装について説明しません。

 
Oracle の構文およびバリエーション
 
CREATE [OR REPLACE] FUNCTION [owner_name.]function_name
[(parameter1 [IN | OUT | IN OUT] [NOCOPY] datatype][,...n)]]
RETURN datatype [DETERMINISTIC | AUTHID {CURRENT_USER | DEFINER} ]
  {IS | AS} {PL/SQL block | external program};
 

Oracle の ユーザー定義関数とストアドプロシージャーは、構成および構造において非常に似ています。主な違いは、ストアドプロシージャーが呼び出しプロセスに対して値を返すことができないのに対して、関数は、呼び出しプロセスに 1 つの値を返すことができます。

 

Oracle のユーザー定義関数で指定する引数とパラメータには、INOUT、および IN OUT があります。IN 修飾子は関数を呼び出すときに指定して、関数に値を渡します。OUT 引数は呼び出しプロセスに値を返します。つまり、IN 修飾子は、関数を呼び出すユーザーまたはプロセスによって提供され、OUT 引数は関数によって返されます。IN OUT 引数は IN および OUT の両方の機能を実行します。OUT または IN OUT 引数が VARRAY や RECORD データタイプのように非常に大きな場合、NOCOPY キーワードを使用するとパフォーマンスが向上します。

 

RETURN キーワードで関数の戻り値のデータタイプを指定します。DETERMINISTIC キーワードを使用すると、関数は明示的に決定性として宣言され、処理が高速化されます。戻り値は、マテリアライズドビュー、同じ関数に対する別の関数の同時呼び出し、または関数ベースのインデックスから格納されます。また、現行ユーザーや関数の所有者がそれぞれ AUTHID CURRENT_USER または AUTHID DEFINER 句を使用する場合の権限で、関数を強制的に実行できます。

 

たとえば、次の関数では、プロジェクト名を指定して建設プロジェクトの利益を求めることができます。

 
CREATE FUNCTION project_revenue (project IN varchar2)
RETURN NUMBER
AS
   proj_rev NUMBER(10,2);
BEGIN
   SELECT SUM(DECODE(action,'COMPLETED',amount,0)) -
          SUM(DECODE(action,'STARTED',amount,0))   +
          SUM(DECODE(action,'PAYMENT',amount,0))
   INTO proj_rev
   FROM construction_actions
   WHERE project_name = project;
   RETURN (proj_rev);
END;
 

この例のユーザー定義関数 (project_revenue) では、プロジェクト名を引数として受け取ります。次に、決済金額から初期費用を減算し、その他の支払い金額を加算することによって、プロジェクトの利益が計算されます。RETURN (proj_rev); の行で、呼び出しプロセスに合計値を返します。

 
PostgreSQL の構文およびバリエーション
 
CREATE FUNCTION name ( [ parameter1 [,...n] ] )
RETURNS datatype
AS {definition | object_file, link_symbol}
LANGUAGE {'C' | 'SQL' | 'PLPGSQL' | 'PLTCL' | 'PLTCLU' | 'PLPERL'
   | 'internal'}
[WITH ISCACHABLE];
 

CREATE FUNCTION の実装に関しては、PostgreSQL が最も柔軟に対応しています。その他の実装と同様、パラメータが呼び出され、指定したデータタイプの値が返されます。また、PostgreSQL では、 関数をオーバーロードでき、関数が別の入力パラメータを受け取っている限りは、同じ関数名でも別の機能を割り当てることができます。

 

WITH ISCACHABLE データタイプ属性を指定すると、関数に同じパラメータ値が与えられた場合、常に同じ値を返すようにして、PostgreSQL のパフォーマンスを最適化します。この設定を行うと、オプティマイザは、関数呼び出しを事前評価できます。

 

definition には、内部関数名、オブジェクトファイルの名前とパス、SQL クエリー、手続き言語で記述されたテキストなど、 関数を定義する文字列を指定できます。文字列は関数を記述する言語に依存します。定義には、C 言語関数に対するオブジェクトファイル名 (object_file) およびリンクシンボル (link_symbol) を指定できます。

 

PostgreSQL の SQL 関数の簡単な例を次に示します。

 
CREATE FUNCTION max_project_nbr
RETURNS int4
AS "SELECT MAX(project_ID) FROM housing_construction AS RESULT"
LANGUAGE 'sql';
 

PostgreSQL では、CREATE FUNCTIONCREATE PROCEDURE の代わりに使用したり、CREATE TRIGGER のアクションを定義するために使用したりします。

 

LANGUAGE キーワードを指定して、PostgreSQL の関数で外部プログラムを呼び出すことができます。それらは他の言語でコンパイルされるプログラムのため、本マニュアルでは説明しません。ただし、SQL のユーザー定義関数を記述するときは、LANGUAGE `sql' 句を使用する必要があります。

 
CREATE INDEX 

インデックスは、テーブルに対して作成する特別なオブジェクトで、SELECTUPDATE、および DELETE ステートメントなどの多くのデータ操作処理を高速化します。インデックスの作成では、インデックス化する列の値の場所および分布 (統計情報) が構築されます。通常、テーブルに作成するインデックスによって、WHERE 句で指定できる範囲が異なります。

 
ベンダーコマンド
SQL Server変則対応
MySQL変則対応
Oracle変則対応
PostgreSQL変則対応
 

CREATE INDEX コマンドはベンダー間で大きく異なります。この理由の 1 つとして、指定テーブル内のデータがディスク上で物理的にソートされる方法や配置される方法を指定するのに CREATE INDEX コマンドを使用している DBMS ベンダーがあることが挙げられます。

 
SQL99 の構文および説明
 
CREATE INDEX index_name ON table_name (column_name [, ...n])
 

すべての主なベンダーでは、複合インデックス (連結インデックス) に対応しています。これらのインデックスは、姓と名など、2 つ以上の列を 1 単位として検索する方法が最適な場合に使用します。

 
Microsoft SQL Server の構文およびバリエーション
 
CREATE [UNIQUE] [CLUSTERED | NONCLUSTERED] INDEX index_name
ON {table | view} (column [ASC | DESC] [,...n])
[WITH [PAD_INDEX]
   [[,] FILLFACTOR = fillfactor]
   [[,] IGNORE_DUP_KEY]
   [[,] DROP_EXISTING]
   [[,] STATISTICS_NORECOMPUTE] ]
[ON filegroup]
GO
 

Microsoft SQL Server では重要なオプションが提供されています。たとえば、昇順または降順インデックスをテーブルに作成したり、ビューおよび計算列 (UPPER(book_name) または ((qty * amt) / royalty) など) にもインデックスを作成したりできます。SQL Server では、UNIQUECLUSTERED、または NONCLUSTERED (デフォルト) のオプション引数も指定できます。UNIQUE を指定すると、列に同じ値のない一意インデックスが作成されます。値の挿入や更新など、インデックス内に重複行ができてしまう操作はすべてエラーとなります。CLUSTERED を指定すると、ディスク上のデータの物理的ソート順序が決まります。NONCLUSTERED を指定すると、テーブルの論理順序が作成され、データ操作処理を高速化します。

 

SQL Server ではこの他にも次の構文を提供しています。

 
  1. PAD_INDEX を指定すると、FILLFACTOR で設定された値に従って、各インデックスデータページに領域が確保されます。
  2. FILLFACTOR にはパーセント値 (1 ~ 100) を指定して、インデックス作成時に 8 KB のデータページを埋める割合を SQL Server に指示します。これを指定すると、8 KB のデータページが埋まった際のページ分割を減少でき、I/O 集約型のディスク処理が減少します。FILLFACTOR を明示的に定義してクラスターインデックスを作成すると、インデックスのサイズを増加でき、特定の環境下の処理を高速化できます。
  3. IGNORE_DUP_KEY は、挿入や更新の操作によって、一意インデックスに重複レコードが作成される場合の動作を制御します。この値を列に設定すると、重複行のみが処理から除外されます。この値を設定しない場合、処理されたレコードは、重複していないレコードも含めてすべてロールバックされます。
  4. DROP_EXISTING は、既存のインデックスをすべて削除し、指定インデックスを再構築する便利な機能です。
  5. STATISTICS_NORECOMPUTE を指定すると、インデックス統計値は再計算されません。これによって、CREATE INDEX 処理は高速化しますが、インデックスはあまり役に立たなくなります。
  6. ON filegroup を指定すると、指定した既存ファイルグループに対するインデックスが作成されます。これによって、特定のハードディスクや RAID デバイスにインデックスを配置できるようになります。
 

インデックスを作成するには、通常、現在テーブルが使用している領域の 1.2 ~ 1.5 倍の 領域が必要となります。インデックス作成後は、その領域のほとんどが解放されます。

 
MySQL の構文およびバリエーション
 
CREATE [UNIQUE] INDEX index_name ON table_name (column_name(length) [,...n])
 

MySQL の CREATE INDEX ステートメントは、基本的な ANSI 規格に対応しています。これには、複数列に対する インデックスの作成機能も含まれます。また、UNIQUE を指定して、インデックスが一意の値しか受け付けないよう定義できます。UNIQUE で作成された一意インデックスのあるテーブルに、一意ではない値を挿入しようとしても拒否されます。

 

MySQL の特徴的な機能として、CHAR または VARCHAR 型の列の最初の数文字 (length) に対してもインデックスを作成できます。これは、たとえば、列の最初の 10 文字だけで十分検索できる場合や、ディスク領域の確保が重要な場合に便利です。

 
Oracle の構文およびバリエーション
 
CREATE [UNIQUE | BITMAP] INDEX [owner_name.]index_name
ON [schema.]{table ({column | expression} [ASC | DESC] [,...n])
   | CLUSTER cluster_name}
[physical_attributes_clause | {LOGGING | NOLOGGING} |
  | [ONLINE] | [COMPUTE [STATISTICS] ]
  | {TABLESPACE tablespace_name | DEFAULT}
  | {COMPRESS int | NOCOMPRESS}
  | {NOSORT |REVERSE} ],...
 [GLOBAL PARTITION BY RANGE (column_list)
   (PARTITION [partition_name] VALUES LESS THAN (value_list)
   [physical_attributes_clause | {LOGGING | NOLOGGING} ] ,...n )
| LOCAL [ (PARTITION [partition_name]
   [physical_attributes_clause | {LOGGING | NOLOGGING} ] ,...n ) ] ]
[PARALLEL [int] | NOPARALLEL]
 

Oracle では、列値に対してだけでなく、UPPER(book_name) または ((qty * amt) / royalty) などの計算式に対してもインデックスを作成できます。インデックスには、一意 (UNIQUE) を指定できますが、一意ではないインデックスも作成できます。Oracle では、BITMAP を指定して、わずかな違いしかない値を持つ列に有用なビットマップインデックスを作成できます。さらに、昇順 (ASC) および降順 (DESC) の両方のインデックスを作成できます。ただし、Oracle では、降順インデックスは関数ベースのインデックスとして処理されます。昇順 (ASC) インデックスと降順 (DESC) インデックスの機能にはいくつかの違いがあります。CLUSTER オプションを使用すると、インデックスにクラスターキーを指定することもできます。クラスターは Oracle 固有のコマンド CREATE CLUSTER で作成します。

 

Oracle と SQL Server では、クラスターインデックスの定義に大きな違いがあります。SQL Server のクラスターインデックス は、テーブルに格納されているデータの物理的なソート順序を指定します。Oracle のクラスターインデックスは、2 つ以上のテーブル間で結合処理を大幅に高速化するための特殊なインデックスです。

 

physical_attributes_clause は、次のように確立できる設定を参照します。

 
[ PCTFREE int
| PCTUSED int
| INITRANS int
| MAXTRANS int
| STORAGE storage...]
 

PCTFREE は、SQL Server の FILLFACTOR と似ています。つまり、新たな挿入および更新用に、インデックス内に確保する空の領域の割合を指定します。PCTFREE は、一意 (UNIQUE) ではないインデックスに対してのみ使用できます。PCTUSED には、挿入のために必ず必要なブロック内の使用可能領域の割合を指定します。PCTUSED はテーブルに指定可能ですが、インデックスには使用されません。STORAGEINITRANS、および MAXTRANS の詳細については、CREATE TABLE ステートメントの項を参照してください。

 

TABLESPACE 句は、インデックスを特定のテーブル領域に割り当てます。TABLESPACE 句を指定しないと、インデックスはデフォルトのテーブル領域に置かれます。または、DEFAULT キーワードを指定しても同じ結果となります。

 

LOGGING を指定すると、REDO ログファイルにインデックスの作成ログが記録され、NOLOGGING を指定するとログが記録されません。このキーワードは、Oracle Direct Loader を使用することによる大量の読み込みに関するデフォルト動作も設定します。インデックスのパーティションを作成する際は、これらのキーワードごとに特殊な動作となるため、詳細についてはベンダーのマニュアルを参照してください。

 

ONLINE を指定すると、インデックスが作成されている間にテーブルでデータ操作を行えます。COMPUTE STATISTICS コマンドはインデックスが作成されている間に統計情報を収集します。統計情報は、比較的低コストで収集されます。COMPRESS を指定すると、パーティション化されていないインデックスに対してキー圧縮を有効にします。これによって、繰り返しキー値が削減され領域が解放されます。COMPRESS に付随する整数値には、圧縮する接頭辞列の数を指定します。デフォルトは NOCOMPRESS で、圧縮を無効にします。

 

Oracle では、 パーティションインデックスおよびパーティションテーブルの作成に PARTITION 句を使用します。このため、Oracle のインデックスでは、パーティションテーブルがサポートされています。LOCAL 句を指定すると、テーブルの各パーティションに対して別々のインデックスを作成できます。GLOBAL 句を指定すると、すべてのパーティションに対して共通のインデックスを作成します。ただし、特定のインデックス値の範囲は、パーティションによって格納されている範囲ごとに異なる場合があります。

 

NOSORT オプションを指定すると、既に昇順にソートされている列に対して素早くインデックスを作成できます。列の値が完全に昇順でない場合、処理は中断されるので、NOSORT オプションを指定せずに再試行できます。REVERSE は対照的に、インデックスブロックを格納領域に逆順に配置します (行 ID は除く)。REVERSE は、NOSORT と相互に排他的で、ビットマップインデックスやインデックス編成テーブルに対しては使用できません。

 

PARALLEL 句を指定すると、別個の CPU によってインデックスを並列に作成でき、処理が高速化します。オプションで指定する整数値によって、この処理で使用する並列スレッドの数が定義されます。デフォルトは NOPARALLEL で、インデックスは直列に作成されます。

 
PostgreSQL の構文およびバリエーション
 
CREATE [UNIQUE] INDEX index_name ON table
[USING [BTREE | RTREE | HASH] ]
(function_name (column [operator_class] [, ...] ))
 

PostgreSQL では、標準的な昇順 インデックス、および一意 インデックスを作成できます。この実装には、WITH access_method 句によるパフォーマンスの向上も含まれます。この句では、パフォーマンスを最適化するための次の 3 つの動的アクセスメソッドのいずれかを実行できます。

 
  • BTREE
      その他のメソッドを指定しない場合、これがデフォルトのメソッドです。このメソッドは、Lehman-Yao による高並行性 btree を利用します。
  • RTREE
      このメソッドは、Guttman の 2 次分割アルゴリズムを使った標準 rtree を利用します。
  • HASH
      このメソッドは、Litwin の線形ハッシュの実装です。
 

PostgreSQL では、列のデータタイプに基づいた関連する演算子クラス (operator_class) を列に指定することもできます。演算子クラスには、特定のインデックスの演算子を指定します。ユーザーは列に有効な任意の演算子クラスを定義できますが、デフォルトでは、フィールドのデータタイプに最適な演算子クラスとなっています。

 

また、PostgreSQL では、関数、ユーザー定義関数、または式を使用してインデックスを定義できます。たとえば、UPPER(book_name) に対してインデックスを定義して、インデックスの基本データに定期的に適用される変換処理を高速化できます。

 
 

MySQL のこの例では、authors テーブルの au_id 列に対して、シンプルな昇順インデックスを作成します。

 
CREATE INDEX au_id_ind
ON authors (au_id);
 

次の例では、CREATE FUNCTION の項で使用した housing_construction テーブルを作成し、そのテーブルに対してクラスターインデックスを配置します。このインデックスでは、CLUSTERED 句が指定されているため、ディスク上に物理的な順序でデータをソートします。

 
CREATE TABLE housing_construction
   (project_number      INT NOT NULL,
   project_date         DATETIME NULL,
   project_name         VARCHAR(50)
       COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
   construction_color   NCHAR(20)
       COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
   construction_height  DECIMAL(4, 1) NULL ,
   construction_length  DECIMAL(4, 1) NULL ,
   construction_width   DECIMAL(4, 1) NULL ,
   construction_volume  INT NULL
GO

CREATE UNIQUE CLUSTERED INDEX project_id_ind
ON housing_construction(project_id)
GO
 

複数列にまたがるインデックス、つまり連結キーを作成する必要のあることがよくあります。次に例を示します。

 
CREATE UNIQUE INDEX project2_ind
ON housing_construction(project_name, project_date)
WITH PAD_INDEX, FILLFACTOR = 80
GO
 

PAD_INDEX 句を追加して、FILLFACTOR を 80 に設定すると、インデックスおよびデータページが 100% 埋まることなく、80% の状態を維持します。

 

次の Oracle の例では、データの格納方法を見るため、特定のテーブル領域に対して同じインデックスを作成します。

 
CREATE UNIQUE INDEX project2_ind
ON housing_construction(project_name, project_date)
STORAGE (INITIAL 10M NEXT 5M PCTINCREASE 0)
TABLESPACE construction;
 

housing_construction テーブルを Oracle のサーバー上のパーティションテーブルとして作成する場合は、パーティションインデックスも作成する必要があります。

 
CREATE UNIQUE CLUSTERED INDEX project_id_ind
ON housing_construction(project_id)
GLOBAL PARTITION BY RANGE (project_id)
   (PARTITION part1 VALUES LESS THAN ('K')
      TABLESPACE construction_part1_ndx_ts,
   PARTITION part2 VALUES LESS THAN (MAXVALUE)
      TABLESPACE construction_part2_ndx_ts);
 
CREATE PROCEDURE 

ストアドプロシージャーは、データベースサーバー環境に、条件処理およびプログラム機能を提供します。ストアドプロシージャーは、渡されたパラメータを受け取り、複雑なタスクを実行するプログラミングコードのカプセルです。ストアドプロシージャーはプリコンパイルされているという点でも非常に便利です。ストアドプロシージャーがタスクを迅速かつ効率的に実行できるのは、データベースオプティマイザがコードの実行計画をビルド済みだからです。

 
ベンダーコマンド
SQL Server対応
MySQL未対応 (CREATE FUNCTION コマンドの項を参照)
Oracle対応
PostgreSQL未対応
 

他の多くの CREATE ステートメント同様、このコマンドはベンダー間で大きく異なっています。

 
SQL99 の構文および説明
 
CREATE PROCEDURE procedure_name
[parameter data_type attributes ][,...n]
AS
code block
 

この SQL99 構文の詳細については、CREATE FUNCTION の項を参照してください。CREATE FUNCTION の高度な機能が、CREATE PROCEDURE にも適用されています。

 

各ベンダーは、独自のプロシージャー型拡張を SQL 言語に実装しているため、本マニュアルでは、ストアドプロシージャーのコーディングについては説明しません。ただし、ストアドプロシージャーのプログラミングの基礎については説明します。O'Reilly 社発行の『Transact-SQL Programming』(Kevin Kline、Lee Gould & Andrew Zanevsky、1999)、オライリー・ジャパン発行の『Oracle PL/SQL プログラミング 基礎編/応用編 第2版などに、それぞれのプログラミング言語に関する詳細な解説があります。

 
Microsoft SQL Server の構文およびバリエーション
 
CREATE PROC[EDURE] procedure_name [;number]
[{@parameter_name datatype} [VARYING] [= default] [OUTPUT]][,...n]
[WITH {RECOMPILE | ENCRYPTION | RECOMPILE, ENCRYPTION}]
[FOR REPLICATION]
AS
Transact-SQL_block
GO
 

Microsoft SQL Server では、プロシージャー名 (procedure_name) に加え、バージョン番号を procedure_name;1 のフォーマットで指定できます。ここでは整数値 1 がバージョン番号を示します。これによって、単一のストアドプロシージャーの複数のバージョンにアクセスできます。

 

テーブル同様 (CREATE TABLE 参照)、ローカル一時プロシージャーおよびグローバル一時プロシージャーを宣言するには、 シャープ記号 (#)、および 2 重のシャープ記号 (##) をそれぞれのプロシージャー名の前に付加します。一時プロシージャーは、一時プロシージャーを作成したユーザーまたはプロセスのセッション期間のみ存在します。セッションが終了すると、一時プロシージャーは自動的に削除されます。

 

SQL Server のストアドプロシージャーには、最初にアットマーク (@)、次に SQL Server の任意のデータタイプを指定して、最高 1024 個の入力パラメータを宣言できます。パラメータに cursor データタイプを指定するには、VARYING および OUTPUT の両方を指定する必要があります。VARYING キーワードは cursor データタイプのパラメータにのみ使用し、結果セットがプロシージャーによって動的に構築されます。

 

入力パラメータの値は、ユーザーまたは呼び出しプロセスによって提供される必要があります。ただし、初期設定値を指定すれば、ユーザーまたはプロセスが値を提供しなくてもプロシージャーを実行できます。初期設定値には、定数または NULL を設定する必要がありますが、LIKE の項で説明しているように、ワイルドカード文字を含めることもできます。

 

同様に、OUTPUT キーワードを使用してパラメータを戻りパラメータに宣言できます。戻りパラメータに格納された値は、SQL Server の EXEC[UTE] コマンドの戻りパラメータを格納する変数を介して任意の呼び出しプロシージャーに返されます。OUTPUT パラメータには、TEXT および IMAGE 型以外の任意のデータタイプを指定できます。

 

省略可能なオプションの WITH RECOMPILEWITH ENCRYPTION、および WITH RECOMPILE, ENCRYPTION について次に示します。

 
  • WITH RECOMPILE
      このオプションを指定すると、ストアドプロシージャーの実行計画がキャッシュされません。その代わり、ストアドプロシージャが実行されるたびに実行計画が再コンパイルされます。これは、プロシージャーで非定型または一時的な値が使用される場合に便利です。
  • WITH ENCRYPTION
      このオプションを指定すると、SQL Server の syscomments テーブルでストアドプロシージャーのコードを暗号化します。
  • WITH RECOMPILE, ENCRYPTION
      2 つのオプションを同時に行います。
 

FOR REPLICATION 句は WITH RECOMPILE 句と相互に排他的で、ストアドプロシージャーをサブスクライブサーバーで実行できないように指定します。これは、SQL Server の組み込みレプリケーションエンジンでのみ実行されるフィルタリングストアドプロシージャの作成に主に使用されます。

 

AS Transact-SQL_block 句には、Transact-SQL コマンドを最大で 128 MB のサイズまで指定します。Microsoft SQL Server では、有効な Transact-SQL ステートメントのほとんどを使用できますが、SET SHOWPLAN_TEXT および SET SHOWPLAN_ALL は使用できません。ストアドプロシージャー内での使用に制限のあるその他のコマンドは、ALTER TABLECREATE INDEXCREATE TABLE、すべての DBCC ステートメント、DROP TABLEDROP INDEXTRUNCATE TABLE、および UPDATE STATISTICS です。

 

SQL Server では、 名前の遅延解決を認めています。これは、作成されていないオブジェクトをストアドプロシージャーが参照した場合でも、エラーを発生せずにコンパイルされる機能です。これによって、オブジェクトがまだ存在しなくても、実行計画が作成され、実行時にのみエラーとなります。

 

SQL Server では、ストアドプロシージャーを簡単にネストできます。ストアドプロシージャーが別のストアドプロシージャーを呼び出すごとに、システム変数の @@NESTLEVEL が 1 ずつ増加し、呼び出されたプロシージャーが完了するごとに、1 ずつ減少します。SELECT @@NESTLEVEL を指定すると、現行セッションのネスト層数が返されます。

 
Oracle の構文およびバリエーション
 
CREATE [OR REPLACE] PROCEDURE [owner_name.]procedure_name
[(parameter1 [IN | OUT | IN OUT] [NOCOPY] datatype][,...n)]]
[AUTHID {CURRENT_USER | DEFINER} ]
{IS | AS} {PL/SQL block | LANGUAGE {java_spec | C_spec}};
 

Oracle の ユーザー定義関数とストアドプロシージャーは、構成および構造において非常に似ています。主な違いは、ストアドプロシージャーが呼び出しプロセスに対して値を返すことができないのに対して、関数は、呼び出しプロセスに 1 つの値を返すことができます。

 

Oracle のストアドプロシージャーで指定する引数とパラメータには、INOUT、または IN OUT があります。IN 修飾子は関数を呼び出すときに指定して、関数に値を渡します。OUT 引数は呼び出しプロセスに値を返します。つまり、IN 修飾子は、関数を呼び出すユーザーまたはプロセスによって提供され、OUT 引数は関数によって返されます。IN OUT 引数は IN および OUT の両方の機能を実行します。OUT または IN OUT 引数が VARRAY や RECORD データタイプのように非常に大きな場合、NOCOPY キーワードを使用するとパフォーマンスが向上します。

 

また、現行ユーザーや関数の所有者がそれぞれ AUTHID CURRENT_USER または AUTHID DEFINER 句を使用する場合の権限で、関数を強制的に実行できます。

 

Oracle では、LANGUAGE キーワードを介してプロシージャーが外部プログラムを呼び出すことができます。外部プログラムは C や Java 言語で記述されるため、本マニュアルでは、外部プログラムを呼び出すための具体的な構文については説明しません。この機能の詳細については、ベンダーのマニュアルを参照してください。

 

Microsoft SQL Server のストアドプロシージャーは、結果セットを返すことができますが、Oracle のストアドプロシージャーは、呼び出しプロセスに結果セットを返すことができません

 
 

次の Microsoft SQL Server のストアドプロシージャーでは、システムの日付と時刻の要素に基づく一意の 22 桁の値を生成し、その値を呼び出しプロセスに返します。

 
-- A Microsoft SQL Server stored procedure
CREATE PROCEDURE get_next_nbr
   @next_nbr CHAR(22) OUTPUT
AS
BEGIN
  DECLARE @random_nbr INT
  SELECT @random_nbr = RAND(  ) * 1000000

SELECT @next_nbr =
  RIGHT('000000' + CAST(ROUND(RAND(@random_nbr)*1000000,0))AS CHAR(6), 6) +
  RIGHT('0000' + CAST(DATEPART (yy, GETDATE(  ) ) AS CHAR(4)), 2) +
  RIGHT('000'  + CAST(DATEPART (dy, GETDATE(  ) ) AS CHAR(3)), 3) +
  RIGHT('00'   + CAST(DATEPART (hh, GETDATE(  ) ) AS CHAR(2)), 2) +
  RIGHT('00'   + CAST(DATEPART (mi, GETDATE(  ) ) AS CHAR(2)), 2) +
  RIGHT('00'   + CAST(DATEPART (ss, GETDATE(  ) ) AS CHAR(2)), 2) +
  RIGHT('000'  + CAST(DATEPART (ms, GETDATE(  ) ) AS CHAR(3)), 3)
END
GO
 
CREATE ROLE 

CREATE ROLE を使用すると、データベースのユーザーに割り当てる権限セットを名前付きで作成できます。ユーザーはロールが付与されると、そのロールの権限および許可もすべて取得します。

 
ベンダーコマンド
SQL Server未対応
MySQL未対応
Oracle変則対応
PostgreSQL未対応
 

Microsoft SQL Server は、CREATE ROLE コマンドをサポートしていませんが、システムのストアドプロシージャー sp_add_role を介して同等の機能を提供しています。

 
SQL99 の構文および説明
 
CREATE ROLE role_name [WITH ADMIN {CURRENT_USER | CURRENT_ROLE}]
 

このステートメントは新しいロール (role_name) を作成し、そのロールをホスト DBMS ユーザーと区別します。WITH ADMIN 句を指定すると、現在アクティブなユーザー (CURRENT_USER)、または現在アクティブなロール (CURRENT_ROLE) に直ちに割り当てられます。デフォルトでは、ステートメントに WITH ADMIN CURRENT_USER と指定されています。

 
Oracle の構文およびバリエーション
 
CREATE ROLE role_name [NOT IDENTIFIED | IDENTIFIED
   {BY password | EXTERNALLY | GLOBALLY}]
 

Oracle では最初にロール (role_name) を作成し、ユーザーと同様に、後から GRANT コマンドを使用して権限および許可をそのロールに付与します。パスワードによって保護されているロールにアクセスする場合は、SET ROLE コマンドを使用します。ロールにパスワード (password) が設定されている場合、そのロールにアクセスするには SET ROLE コマンドを使用してパスワードを提供する必要があります。

 

Oracle では、事前構成済みのロールをいくつか提供しています。CONNECTDBA、および RESOURCE は Oracle のすべてのバージョンで有効です。EXP_FULL_DATABASE および IMP_FULL_DATABASE は、インポート処理とエクスポート処理に使用する新しいロールです。

 
 

次の例では、CREATE を使用して、Oracle の新しいロールを作成し、GRANT を使用してそのロールに権限を付与します。次に、ALTER ROLE でそのロールにパスワードを割り当て、GRANT でロールを 2 人のユーザーに付与します。

 
CREATE ROLE boss;

GRANT ALL ON employee TO boss;
GRANT CREATE SESSION, CREATE DATABASE LINK TO boss;

ALTER ROLE boss IDENTIFIED BY le_grande_fromage;

GRANT boss TO nancy, dale;
 
CREATE SCHEMA 

このステートメントは、スキーマ、つまり関連オブジェクトの名前付きグループを作成します。スキーマはテーブル、ビュー、および関連する権限の集まりです。スキーマは、既存の有効なユーザー ID (所有者) に関連付けられます。

 
ベンダーコマンド
SQL Server対応
MySQL未対応
Oracle変則対応
PostgreSQL未対応
 
SQL99 の構文および説明
 
CREATE SCHEMA [schema_name] [AUTHORIZATION owner_name]
[DEFAULT CHARACTER SET char_set_name]
[PATH schema_name [,...n] ]

   [ <create_table_statement1> [...n] ]
   [ <create_view_statement1>  [...n] ]
   [ <grant statement1> [...n] ]
 

CREATE SCHEMA ステートメントには、CREATEGRANT など、他の多くのステートメントを格納できます。オプションとして、DEFAULT CHARACTER SET を指定すると、スキーマのデフォルトの文字セットを指定できます。ファイルシステムにあるスキーマ内の任意のオブジェクトに対して PATH も宣言できます。

 
Microsoft SQL Server および Oracle の構文
 
CREATE SCHEMA AUTHORIZATION owner_name
   [ <create_table_statement1> [...n] ]
   [ <create_view_statement1>  [...n] ]
   [ <grant statement1> [...n] ]
 

CREATE SCHEMA ステートメント内のあるステートメントが失敗した場合、ステートメント全体が失敗します。CREATE SCHEMA の利点の 1 つは、従属関係などに応じてステートメント内のオブジェクトを編成する必要がない点です。たとえば、GRANT ステートメントは通常、存在していないテーブルに対して発行できません。しかし、すべての GRANT ステートメントは、最初に CREATE SCHEMA ステートメント内に置くことができ、その後に、権限を与える対象を作成する CREATE ステートメントを配置できます。

 

CREATE SCHEMA コマンドを明示的にサポートしている実装はほとんどありません。ただし、ユーザーがデータベースオブジェクトを作成すると、スキーマは暗黙的に作成されます。一方、Oracle では、ユーザーが作成されるたびにスキーマが作成されます。CREATE SCHEMA コマンドは単に、テーブル、ビュー、およびその他のデータベースオブジェクトをそれらの権限と共に 1 回の手順ですべて作成する方法です。

 
 

Oracle では、CREATE SCHEMA ではスキーマは作成されません。CREATE USER によってのみスキーマが作成されます。CREATE SCHEMA を使用すると、1 つの SQL ステートメントで複数の手順を実行できます。次の Oracle の例では、CREATE SCHEMA ステートメント内でオブジェクトを作成する前に権限を設定しています。

 
CREATE SCHEMA AUTHORIZATION emily
   GRANT SELECT, INSERT ON view_1 TO sarah
   GRANT ALL ON table_1 TO sarah

   CREATE VIEW view_1 AS
      SELECT column_1, column_2
      FROM table_1
      ORDER BY column_2

   CREATE TABLE table_1(column_1 INT, column_2 CHAR(20));
 
CREATE TABLE 

CREATE TABLE ステートメントは文字通り、テーブルを作成します。ただし、多くのベンダーでは、CREATE TABLE ステートメントを使用して、キー、カスケードの参照整合性、制約、および初期設定値の指定など、多様なその他の機能を実現できます。

 
ベンダーコマンド
SQL Server変則対応
MySQL変則対応
Oracle変則対応
PostgreSQL変則対応
 

このコマンドは、テーブル名、テーブルの構成列、および列とテーブルのプロパティを定義します。通常、テーブルの設計および作成には、多くの検討を重ねます。このような作業は、データベース設計 と呼ばれます。テーブルとそのテーブル内のデータとの関係、および、テーブルとデータベース内の別のテーブルとの関係を分析する作業を正規化といいます。

 

プログラマーおよび開発者は、このデータベース設計と正規化の原則を熟知したうえで、CREATE TABLE コマンドを発行することをお勧めします。

 

一般的に、テーブル名の先頭には常に英字が使用されます。使用可能な名前の長さはベンダーによって異なります。Oracle では 30 文字のみですが、必要な場合は 30 文字より長い名前を設定できます。数値はテーブル名に使用できますが、記号は アンダースコア (_) しか使用できません。ベンダーによっては、その他の多くの記号をテーブル名に使用できますが、混乱の元になる可能性があるため、それらの記号は使用しないことをお勧めします。

 

すべてのベンダーは列特性の定義で、NULL および NOT NULL オプションをサポートしています。NULL オプションは、SQL99 の要件ではありません。列を NULL として定義した場合、列のデータタイプにかかわらず、その列は NULL 値を含むことができます。通常、NULL を含むことのできる列は、レコードごとに 1 ビット余分に領域を消費します。NOT NULL を指定した場合、その列は NULL 値を含むことはできません。NOT NULL 列に対して、NULL 値を挿入する INSERT 処理や、値を NULL に変更する UPDATE 処理はすべて失敗し、ロールバックされます。

 

また、すべてのベンダーでは、列レベルおよびテーブルレベルの両方で主キー (PRIMARY KEY) 宣言をサポートしています。主キーは、テーブルの各行を一意に識別する方法を表す特殊な標識です。主キーはテーブル内の列から構成され (複数列の指定も可能)、各行に一意の識別子を提供します。テーブルに設定できる主キーは 1 つのみです。主キー内のすべての値は一意である必要があり、NULL を含むことはできません。主キーが設定されていれば、テーブルで外部キーを宣言し、別のテーブルの主キーとの直接的な関係を確立できます。このようにして、親/子、またはマスター/詳細の関係をテーブル間で作成できます。カスケードアクションによって、このアクションをさらに強化できます。たとえば、ある顧客の売上レコードが sales テーブルにある場合、customer テーブルにあるその顧客レコードの削除を防止するなどのアクションです。外部キーの構文はベンダー間で異なります。

 

ほとんどのベンダーでは、DEFAULT キーワードを使用して指定列に初期設定値を設定できます。テーブルにレコードが挿入される際に、この列に値が提供されない場合は、初期設定値が挿入されます。

 

次に CREATE TABLE の基本構文を示します。テーブルを作成し、データを入力するにはこれで十分です。

 
CREATE TABLE table_name
   (
   column_name datatype[(length)] [NULL | NOT NULL],...n
   )
 

次に簡単な例を示します。

 
CREATE TABLE housing_construction
   (project_number      INT NOT NULL,
   project_date         DATETIME NOT NULL,
   project_name         VARCHAR(50) NOT NULL,
   construction_color   NCHAR(20) NULL,
   construction_height  DECIMAL(4,1) NULL,
   construction_length  DECIMAL(4,1) NULL,
   construction_width   DECIMAL(4,1) NULL,
   construction_volume  INT NULL)
GO
 

Microsoft SQL Server のこのステートメントでは、8 つの列を含む housing_construction というテーブルを定義します。各列には、その列に含まれる情報の適切なデータタイプと共に、NULL または NOT NULL が定義されています。列定義のリストは常にかっこで囲まれ、次に定義が続く場合は コンマで各列定義が区切られます。

 
SQL99 の構文および説明
 
CREATE [GLOBAL TEMPORARY | LOCAL TEMPORARY] TABLE table_name
[ON COMMIT {PRESERVE ROWS | DELETE ROWS}
(column_name datatype attributes [,...n]
 | [LIKE  table_name]
 | [table_constraint][,...n] ]
 

SQL99 の CREATE TABLE ステートメントでは、テーブルの作成時にインスタンス化され、現行のユーザーセッションの終了時に自動的に削除される一時 (TEMPORARY ) テーブルを作成できます。一時テーブルとして、すべてのアクティブユーザーセッションで使用できるグローバル (GLOBAL) テーブル、または一時テーブルを作成したユーザーセッションでのみ使用できるローカル (LOCAL) テーブルを作成できます。一時テーブルには、ON COMMIT 句も指定できます。ON COMMIT PRESERVE ROWS を指定すると、COMMIT が実行された場合に、一時テーブルでのすべてのデータ変更が保存されます。ON COMMIT DELETE ROWS を指定すると、COMMIT 後に一時テーブルの行が空になります。

 

LIKE table_name オプションを指定すると、既存のテーブルと同じ列定義およびテーブル制約の新しいテーブルが作成されます。LIKE を使用する場合、列やテーブルの制約を定義する必要はありません。

 

CREATE TABLE の実装はベンダー間で大きく異なり、このコマンドは重要なため、各ベンダーの実装の詳細については別々に説明します。

 
Microsoft SQL Server の構文およびバリエーション
 
CREATE TABLE [database_name.[owner]. | owner.] table_name
({column_name datatype [ [DEFAULT default_value]
   | {IDENTITY [(seed,increment) [NOT FOR REPLICATION]]]
   [ROWGIDCOL] ]
   [NULL | NOT NULL]
   | [{PRIMARY KEY | UNIQUE}
        [CLUSTERED | NONCLUSTERED]
        [WITH FILLFACTOR = int] [ON {filegroup | DEFAULT}] ]
   | [[FOREIGN KEY]
        REFERENCES reference_table[(reference_column[,...n])]
        [ON DELETE {CASCADE | NO ACTION}]
        [ON UPDATE {CASCADE | NO ACTION}]
        [NOT FOR REPLICATION]
   | [CHECK [NOT FOR REPLICATION] (expression)
   | [COLLATE collation_name]
|column_name AS computed_column_expression
[,...n]
|[table_constraint][,...n] )
[ON {filegroup | DEFAULT} ]
[TEXTIMAGE_ON {filegroup | DEFAULT} ]
 

SQL Server では、テーブル、列、およびテーブルレベルの制約を定義する際に、多くのオプションが提供されています。CONSTRAINT constraint_name に続けて制約の内容を指定すると、任意の列レベルの制約も名前付きで指定できます。PRIMARY KEYNULL など、相互に排他的でない限りは 1 つの列に複数の制約を指定できます。

 

SQL Server では、ローカル一時テーブルの作成も可能で、これは、tempdb データベース内に、テーブル名の先頭に 1 つの シャープ記号 (#) を付けて格納されます。ローカル一時テーブルは、作成したユーザーまたはプロセスで使用でき、ユーザーがログアウトするか、またはプロセスが終了すると削除されます。 グローバル一時テーブルは、現在ログインしているすべてのユーザーおよびプロセスで使用でき、テーブル名の先頭に 2 つのシャープ記号 (##) 付けて作成できます。グローバル一時テーブルは、プロセスが終了するか、または作成者がログアウトすると削除されます。

 

SQL Server は組み込みレプリケーションをサポートしているため、列プロパティの多くは NOT FOR REPLICATION に設定できます。これは、IDENTITYFOREIGN KEY の値がサブスクライブサーバーにレプリケートされないようにします。この設定は、データはすべて同じではなく、構造が同じテーブルが別々のサーバーで必要とされる場合に便利です。

 

また、ROWGUIDCOL もレプリケーションに有効です。これを指定すると、列がグローバル一意識別子として識別され、複数のサーバーにおいて値が重複しないようになります。グローバルで一意な列として識別できるのは、1 つのテーブルにつき 1 つの列のみです。ただし、この指定では一意の値は作成されません。作成するには、NEWID 関数を使用して挿入する必要があります。

 

IDENTITY プロパティを指定すると、整数型の列に適用する場合、MySQL の AUTO_INCREMENT と同じように、一意の増分数で列の値を自動的に生成します。ただし、これは AUTO_INCREMENT に比べ、より万能で柔軟性があります。AUTO_INCREMENT が常に 1 から開始されるのに対して、IDENTITY は、seed に指定した数から計算を開始します。また、AUTO_INCREMENT は新しい行が挿入されるたびに 1 ずつ増加するのに対して、IDENTITY では、increment に指定した数だけ増加します。

 

SQL Server では、timestamp データタイプの列や IDENTITY プロパティを持つ列以外の任意の列に、DEFAULT を使用して初期設定値を適用できます。DEFAULT で定義できるのは、文字列や数などの定数値、GETDATE( ) などのシステム関数、または NULL だけです。

 

PRIMARY KEY は、1 つのテーブルにつき 1 つだけ指定でき、UNIQUE または FOREIGN KEY 列は、1 つのテーブルに複数指定できます。これらにクラスター化または非クラスター化の指定、および開始時の埋め込み要素の定義を行えます。詳細については、CREATE INDEX の項を参照してください。

 

FOREIGN KEY を指定する場合、参照整合性を維持するテーブルおよび列を、REFERENCES 句を使用して指定できます。これにより、参照テーブル内で PRIMARY KEY または UNIQUE インデックスとして定義されている列のみを参照できます。参照アクションは、レコードの削除または更新時に reference_table に対して行われるよう指定できます。NO ACTION を指定した場合、レコードが削除または更新されても、参照テーブルでは何も起こりません。CASCADE を指定すると、親テーブルでの削除や更新は、FOREIGN KEY の値に従属する参照テーブル内のすべてのレコードに対して反映されます。

 

CHECK 制約を指定すると、テーブルの指定列に挿入された値が CHECK 式に基づく有効な値に制限されます。列レベルの制約をテーブルに複数指定する例を次に示します。

 
CREATE TABLE people
    (people_id     CHAR(4)
        CONSTRAINT pk_dist_id PRIMARY KEY CLUSTERED
        CONSTRAINT ck_dist_id CHECK (dist_id LIKE '[A-Z][A-Z][A-Z][A-Z]'),
     people_name   VARCHAR(40) NULL,
     people_addr1  VARCHAR(40) NULL,
     people_addr2  VARCHAR(40) NULL,
     city          VARCHAR(20) NULL,
     state         CHAR(2)     NULL
        CONSTRAINT def_st DEFAULT ("CA")
        CONSTRAINT chk_st REFERENCES states(state_ID),
     zip           CHAR(5)     NULL
        CONSTRAINT ck_dist_zip
        CHECK(zip LIKE '[0-9][0-9][0-9][0-9][0-9]'),
     phone         CHAR(12)    NULL,
     sales_rep     empid       NOT NULL DEFAULT USER)
GO
 

people_id 列に対する CHECK 制約では、すべてアルファベットの ID に制限されています。また、zip 列に対する制約では、すべて数値に制限されています。state 列に対する REFERENCES 制約では、states テーブルに対する参照が行われます。REFERENCES 制約は基本的に CHECK 制約と同じですが、REFERENCES 制約では、別の列に格納されている値から許容値のリストを導き出すことができます。この例では、CONSTRAINT constraint_name. . . 構文を使用して列レベル制約を指定する方法を示しています。

 

また、SQL Server 2000 の新機能に COLLATE 列レベルプロパティがあります。この機能によって、列で使用されるソート順序および文字セットを列ごとに変更できます。これは高度な機能なため、列のデフォルトのソート順序や文字セットを変更する必要がある場合は、ベンダーのマニュアルを参照してください。CREATE FUNCTION の項でこの構文の例を示しています。

 

また、SQL Server では、計算値を含む列を持つテーブルを作成できます。データは、実際には列に格納されません。この列は仮想列で、テーブルに既にある他の列を使用した式が格納されます。たとえば、計算列には、order_cost AS (price * qty) などの式を指定できます。計算列には、定数、関数、変数、非計算列、またはこれらを演算子で任意に組み合わせたものも使用できます。

 

ここまで示した列レベルの制約はすべて、テーブルレベルでも宣言できます。つまり、PRIMARY KEY 制約、FOREIGN KEY 制約、CHECK 制約、およびその他の制約を、CREATE TABLE ステートメントで定義されたすべての列に対して宣言できます。これは、複数の列を制限する制約に対して非常に便利です。たとえば、列レベルの UNIQUE 制約を宣言する場合、この制約はその列にのみ適用されます。しかし、テーブルレベルで制約を宣言すると、その制約は複数の列に適用されます。列レベルおよびテーブルレベルの両方の制約の例を次に示します。

 
-- Creating a column-level constraint
CREATE TABLE favorite_books
    (isbn          CHAR(100)    PRIMARY KEY NONCLUSTERED,
     book_name     VARCHAR(40)  UNIQUE,
     category      VARCHAR(40)  NULL,
     subcategory   VARCHAR(40)  NULL,
     pub_date      DATETIME     NOT NULL,
     purchase_date DATETIME     NOT NULL)
GO

-- Creating a table-level constraint
CREATE TABLE favorite_books
    (isbn          CHAR(100)    NOT NULL,
     book_name     VARCHAR(40)  NOT NULL,
     category      VARCHAR(40)  NULL,
     subcategory   VARCHAR(40)  NULL,
     pub_date      DATETIME     NOT NULL,
     purchase_date DATETIME     NOT NULL,
        CONSTRAINT pk_book_id   PRIMARY KEY NONCLUSTERED (isbn)
           WITH FILLFACTOR=70,
        CONSTRAINT unq_book     UNIQUE CLUSTERED (book_name,pub_date))
GO
 

これら 2 つのコマンドは、ほぼ同じ結果を返します。違いは、テーブルレベルの UNIQUE 制約は 2 つの列を含み、列レベルの UNIQUE 制約では 1 つの列だけを含みます。

 

最後に、Microsoft SQL Server には、テーブル (または主キーや一意インデックス) の物理的な配置方法を制御する [ON {filegroup | DEFAULT} ] および [TEXTIMAGE_ON {filegroup | DEFAULT}] の 2 つの句があります。ON filegroup 句は、テーブルまたはインデックスを指定ファイルグループに格納します。ファイルグループはデータベース内に存在している必要があります。ON DEFAULT を指定しているか、ON 句を全く使用していない場合、テーブルまたはインデックスは、データベースのデフォルトのファイルグループに格納されます。TEXTIMAGE 句もほぼ同じように機能しますが、違いはこの句が textntext、および image 列の配置を制御することです。これらの列は通常、その他のすべてのテーブルおよびデータベースオブジェクトと共にデフォルトのファイルグループに格納されます。

 
MySQL の構文およびバリエーション
 
CREATE [TEMPORARY] TABLE [IF NOT EXISTS] table_name
(column_name datatype [NULL | NOT NULL] [DEFAULT default_value]
   [AUTO_INCREMENT]
   [PRIMARY KEY] [reference_definition] |
   [CHECK (expression) |
   [INDEX [index_name] index_col_name1[(length)],...n)] |
   [UNIQUE [INDEX] [index_name] (index_col_name1,...n)] |
   [CONSTRAINT symbol] FOREIGN KEY index_name (index_col_name1,...n)
      [REFERENCES table_name [(index_col_name,...)]
      [MATCH FULL | MATCH PARTIAL]
      [ON DELETE {RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT}]
      [ON UPDATE {RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT}])
{[TYPE = {ISAM | MYISAM | HEAP} |
   AUTO_INCREMENT = int |
   AVG_ROW_LENGTH = int |
   CHECKSUM = {0 | 1} |
   COMMENT = "string" |
   DELAY_KEY_WRITE = {0 | 1} |
   MAX_ROWS = int |
   MIN_ROWS = int |
   PACK_KEYS = {0 | 1} |
   PASSWORD = "string" |
   ROW_FORMAT= { default | dynamic | static | compressed }] }
[[IGNORE | REPLACE] SELECT_statement]
 

MySQL では、テーブルを作成する際に多くのオプションがあります。TEMPORARY オプションは、表作成時の接続期間のみ存続するテーブルを作成します。接続が切断されると、一時テーブルは自動的に削除されます。IF NOT EXISTS オプションを指定すると、テーブルが既に存在する場合のエラーを防止します。

 

MySQL でテーブルを作成する場合は、拡張子が .frm のテーブル定義ファイル、拡張子 .myd のデータファイル、拡張子 .myi のインデックスファイルの、通常 3 つのオペレーティングシステムファイルが作成されます。

 

AUTO_INCREMENT 句は、整数型の列の値が 1 から開始して自動的に 1 ずつ増加するように設定します。MySQL で指定できる AUTO_INCREMENT 列は、1 つのテーブルに対して 1 つのみです。最大値が削除された場合は、その値は再利用されます。レコードがすべて削除された場合は、最初の値から開始されます。

 

PRIMARY KEY 列を定義するには、その列を NOT NULL としても定義する必要があります。INDEX 特性を列に割り当てる場合は、そのインデックスの名前も指定できます。インデックス (INDEX) の MySQL でのシノニムは、キー (KEY) です。名前を指定しない場合、MySQL では、index_column_name の名前に数字の接尾辞 ( _2、_3、. . . ) を追加してその名前を一意にします。NULL 列、または BLOBTEXT データタイプ列に対するインデックスは、MyISAM テーブル型でのみサポートされています。

 

FOREIGN KEYCHECK、および REFERENCES 句は何も行いません。これらの句にはテーブルに対する機能はなく、他の SQL データベースとの互換性を保つためだけに用意されています。

 

テーブルの TYPE オプションは、データの物理的な格納方法を指定します。ISAM は本来のテーブル定義です。MyISAM は比較的新しい構造で、移植性の高いバイナリの格納構造です。HEAP は、テーブルをメモリに格納します。その他のオプションは、テーブルパフォーマンスを最適化するために存在します。

 
  • AUTO_INCREMENT
      自動増分 (AUTO_INCREMENT) 値をテーブルに設定します (MyISAM のみ)。
  • AVG_ROW_LENGTH
      可変サイズのレコードを持つテーブル行のおおよその平均長を設定します。MySQL では、AVG_ROW_LENGTH * MAX_ROWS を使用してテーブルの大きさを求めます。
  • CHECKSUM
      1 に設定すると、テーブル内のすべての行に対するチェックサムを維持します (MyISAM のみ)。これによって処理速度は遅くなりますが、破損しにくくなります。
  • COMMENT
      60 文字までのコメントを指定します。
  • DELAY_KEY_WRITE
      1 に設定すると、テーブルを閉じるまでキーテーブルの更新を遅らせます (MyISAM のみ)。
  • MAX_ROWS
      テーブルに格納できる最大行数を設定します。デフォルトの最大領域は 4 GB です。
  • MIN_ROWS
      テーブルに格納できる最小行数を設定します。
  • PACK_KEYS
      1 に設定した場合、テーブルのインデックスを圧縮します。これによって読み取り速度が向上しますが、更新は遅くなります (MyISAM および ISAM のみ)。デフォルトでは、文字列のみが圧縮されます。1 に設定すると、文字列および数値の両方が圧縮されます。
  • PASSWORD
      .frm ファイルをパスワードで暗号化しますが、テーブルは暗号化しません。
  • ROW_FORMAT
      行を今後どのようにテーブルに格納するかを定義します。
 

SELECT_statement 句を使用すると、SELECT ステートメントの要素に基づくフィールドを持つテーブルが作成されます。そのようにならない場合には、一部の実装のように、テーブルに SELECT ステートメントの結果を書き込むことができます。次に例を示します。

 
CREATE TABLE test_example
  (column_a INT NOT NULL AUTO_INCREMENT,
  PRIMARY KEY(column_a),
  INDEX(column_b))
TYPE=HEAP
SELECT column_b,column_c FROM samples;
 

この例では、column_acolumn_b、および column_c の 3 つの列を持つヒープテーブルが作成されます。

 
Oracle の構文およびバリエーション
 
CREATE [GLOBAL TEMPORARY] TABLE [schema.]table_name
( column_name datatype [DEFAULT] {column_constraint [...]} [,...n]
| table_constraint [,...n] } )
[ON COMMIT {DELETE | PRESERVE} ROWS]
( physical_characteristics )
( table_characteristics )
 

このコードブロックがシンプルで小さいのは見かけだけです。Oracle の CREATE TABLE ステートメントの極めて高度な実装は、単一のコマンドとしては、すべてのプログラミング言語の中で最も複雑な実装である可能性があります。

 

Oracle の CREATE TABLE 句のコードには、従属句が多く含まれます。それらを 1 つのコマンド内ですべて示すよりも、そのコマンドを従属句ごとに分け、さらにそれに含まれる各従属句について説明します。この中には、平均的な SQL プログラマーにほとんど使用されることのない従属句もいくつかあります。

 

SQL99 バージョンの CREATE TABLE と Oracle のバージョンの最も大きな違いは、GLOBAL TEMPORARY として作成されるテーブルが基本テーブルでなければならない点です。グローバル一時テーブルでは、Oracle が通常のテーブルで認めているパーティショニング、インデックス編集、またはテーブルのクラスター化などのほとんどの特殊機能を使用できません。グローバル一時テーブルはすべてのセッションで使用できますが、グローバル一時テーブルに格納されているデータは、そのデータを挿入したセッションでしか参照できません。ON COMMIT 句は、一時テーブルの作成時にのみ使用でき、各コミット後にテーブルを削除 (DELETE ROWS) するか、セッション終了時にテーブルを削除 (PRESERVE ROWS) するかを指定します。次に例を示します。

 
CREATE GLOBAL TEMPORARY TABLE shipping_schedule
  (ship_date DATE,
   receipt_date DATE,
   received_by VARCHAR2(30),
   amt NUMBER)
ON COMMIT PRESERVE ROWS;
 

上記の CREATE TABLE ステートメントでは、shipping_schedule という名前のグローバル一時テーブルが作成され、挿入された行を複数セッション間で保有します。

 

Oracle のテーブルの物理特性は、次のコードブロックおよびサブコードブロックを使用して定義します。

 
-- physical_characteristics
{[{[physical_attributes]
| TABLESPACE tablespace_name
| {LOGGING | NOLOGGING} }]
| {ORGANIZATION {HEAP [{[physical_attributes]
   | TABLESPACE tablespace_name
   | {LOGGING | NOLOGGING} }]
| INDEX indexed_table_clause)}
| CLUSTER cluster_name (column [,...n]) }
[special_storage_clause]
 

physical_characteristics 句は、ディスクサブシステム上にデータが物理的に格納される方法を制御します。

 

TABLESPACE 句は、テーブルを特定の既存テーブル領域に割り当てます。TABLESPACE 句を指定しない場合、デフォルトのテーブル領域にインデックスが配置されます。DEFAULT キーワードを使用しても同じ結果になります。

 

LOGGING および NOLOGGING 句は、テーブル、ラージオブジェクト (LOB)、またはパーティションを REDO ログファイルに記録するかどうかを定義します。

 

ORGANIZATION HEAP 句を指定すると、任意の順序でテーブルの行を物理的に配置します。オプションで、segment_characteristic 句を指定できます。一方、ORGANIZATION INDEX index_name を使用すると、テーブルの行を指定インデックスに基づいて物理的にソートできます。

 

次のコードブロックに示されている physical_attributes 句を指定すると、テーブル全体の記憶域特性を定義できます。また、テーブルがパーティション化されている場合 (詳細については後述) は、指定のパーティションの記憶域特性を定義できます。

 
-- physical_attributes
[{PCTFREE int | PCTUSED int | INITRANS int | MAXTRANS int | storage_
    clause}]
 

PCTFREE は、テーブル内の各データブロックに対して確保する空き領域の割合をパーセントで定義します。たとえば、値 10 を指定すると、挿入される新しい行のためにデータ領域の 10% が確保されます。PCTUSED は、新しい行を挿入するために必要な、ブロック内の空き領域の割合の最小値をパーセントで定義します。たとえば、値 90 を指定すると、使用領域が 90% を下回った場合にデータブロック内に新しい行が挿入されます。PCTFREEPCTUSED の合計値は 100 を超えることはできません。INITRANS はほとんど使用しません。これは、データブロックに対する 1 ~ 255 番目の初期トランザクションの割り当てを定義します。MAXTRANS は、1 つのデータブロック上の同時トランザクションの最大数を定義します。

 

storage_clause は、次に示すように、データの物理的な格納方法を規定する多くの属性を制御します。

 
-- storage_clause
STORAGE ( [ {INITIAL int [K | M]
            | NEXT int [K | M]
            | MINEXTENTS int
            | MAXEXTENTS {int | UNLIMITED}
            | PCTINCREASE int
            | FREELISTS int
            | FREELIST GROUPS int
            | OPTIMAL [{int [K | M] | NULL}]
            | BUFFER_POOL {KEEP | RECYCLE | DEFAULT} ] [...] )
 

storage_clause 句の属性を記述する場合は、(INITIAL 32M NEXT8M) のようにかっこで囲み、各属性をスペースで区切ります。INITIAL int [K | M] は、テーブルの初期エクステントサイズを、バイト単位、キロバイト単位 (K)、またはメガバイト単位 (M) で設定します。NEXT int [K | M] は、INITIAL で指定したエクステントが使用された後に割り当てる追加領域のサイズを指定します。PCTINCREASE int は、最初の増分後のオブジェクトの増分率を制御します。初期エクステントは指定値が割り当てられます。第 2 エクステントは、NEXT で指定されたサイズです。第 3 エクステントは、NEXT + (NEXT * PCTINCREASE) となります。PCTINCREASE を 0 に設定した場合、NEXT が常に使用されます。そうでない場合は、記憶領域の追加分エクステントはそれぞれ前のエクステントの PCTINCREASE 分だけ大きくなります。

 

MINEXTENTS int は、最小エクステント数を指定します。デフォルトでは 1 つのみ作成されますが、オブジェクトが初期化されている場合は、より多くのエクステントが作成されます。MAXEXTENTS int では、エクステントの最大許容数を指定します。これは、無制限 (UNLIMITED) に設定できます。ただし、UNLIMITED はデータベースを破損する可能性があるため、注意して使用する必要があります。FREELISTS int は、各グループに空リストの数を指定します。デフォルトは 1 です。FREELIST GROUPS int は、空リストのグループ数を設定します。デフォルトは 1 です。次に例を示します。

 
CREATE TABLE book_sales
  (qty NUMBER,
   period_end_date DATE,
   period_nbr NUMBER)
TABLESPACE sales
STORAGE (INITIAL 8M NEXT 8M MINEXTENTS 1 MAXEXTENTS 8);
 

books_sales テーブルは sales テーブル領域に定義され、初期領域 8 MB を消費し、最初のエクステントが消費された場合にさらに 8 MB 増加するよう指定されています。このテーブルには最小 1、最大 8 のエクステントが割り当てられているので、最大サイズは 64 MB に制限されます。

 

ORGANIZATION HEAP 句を指定すると、任意の順序でテーブルの行を物理的に配置します。これは、オプションとして、segment_characteristic_clause を指定できます。一方、テーブルの行を指定インデックス (INDEX) に基づいて物理的にソートできます。

 

CLUSTER 句は、テーブルを、クラスターキーに基づく既存のクラスター内に含めます。詳細については、Oracle の CREATE CLUSTER コマンドの説明を参照してください。クラスター内のすべてのテーブルには、クラスターキーの列に対応する列が必要です。

 

special_storage_clause には、Oracle テーブル内で使用可能な LOB (イメージファイルなどのラージオブジェクト) 型、VARRAY 型、および NESTED TABLE 型の 3 つの特殊なデータ記憶型を指定します。

 
{LOB { (LOB_item [,n]) STORE AS {ENABLE | DISABLE} STORAGE IN ROW
      | (LOB_item) STORE AS
           {LOB_segment_name ({ENABLE | DISABLE} STORAGE IN ROW)
           | LOB_segment_name
           | ({ENABLE | DISABLE} STORAGE IN ROW)}
  | VARRAY varray_item STORE AS
  | NESTED TABLE nested_item STORE AS storage_table
      [(physical_characteristics)]
      [RETURN AS {LOCATOR | VALUE}] }
 

LOB 句は、LOB データセグメントの記憶属性を定義します。LOB の項目は、テーブルで宣言された LOB 列の名前です。LOB オブジェクトは、長さが 4,000 バイト未満の場合、ENABLE STORAGE IN ROW 句を使用して行に格納できます。また、DISABLE STORAGE IN ROW 句を使用すると、サイズにかかわらず行外に保存されます。LOB_storage_clause を使用した LOB 記憶域の詳細については、Oracle のマニュアルを参照してください。次に例を示します。

 
CREATE TABLE large_objects
  (pretty_picture BLOB,
   interesting_text CLOB)
STORAGE (INITIAL 256M NEXT 256M)
LOG (pretty_picture, interesting_text)
   STORE AS (TABLESPACE large_object_segment
      STORAGE (INITIAL 512M NEXT 512M)
      NOCACHE LOGGING);
 

large_objects テーブルは、イメージおよびテキストの格納に使用されています。ここでは、記憶特性に加えてログおよびキャッシュ特性も詳細に指定されています。

 

VARRAY は、Oracle 独自のオブジェクトです。Oracle では、LOB 句と基本的に同じ構文を使用して、VARRAY 型で格納される LOB に対して個別に記憶パラメータを指定できます。VARRAY の詳細については、ベンダーのマニュアルを参照してください。

 

Oracle では、テーブルが別のテーブルの列に仮想的に格納される NESTED TABLE 句を宣言できます。STORE AS 句では、テーブル内のテーブルに対してプロキシ名を指定できますが、ネストするテーブルはユーザー定義のデータタイプで最初に作成する必要があります。この機能は、値がまばらに配置されている場合は有効ですが、通常、日々のタスクには推奨されません。次に例を示します。

 
CREATE TYPE prop_nested_tbl AS TABLE OF props_nt;

CREATE TABLE proposal_types
   (proposal_category VARCHAR2(50),
   proposals          PROPS_NT)
NESTED TABLE props_nt STORE AS props_nt_table;
 

Oracle では、テーブルに対して、様々なテーブル特性を定義できます。これらの特性のいくつかを次に示します。

 
-- table_characteristics
{ PARTITION characteristics }
[CACHE | NOCACHE] [MONITORING | NOMONITORING]
[{NOPARALLEL | PARALLEL [int] }]
[{ENABLE | DISABLE} [VALIDATE | NOVALIDATE]
  {UNIQUE (column [,...n] )
  | PRIMARY KEY
  | CONSTRAINT constraint_name}
[index_clause]
[EXCEPTION INTO [schema.]table_name]
[CASCADE] ]
[AS select_statement]
 

Oracle では、PARTITION 句を使用して、テーブルを複数のパーティションに分割することによって、パフォーマンスが向上します。テーブルパーティションのすべてを記述する完全な構文は、非常に長くなります。さらに、経験の少ない SQL プログラマーがこの構文を使用することはほとんどありません。テーブルパーティションの詳細については、Oracle のマニュアルを参照してください。

 

CACHE を指定すると、高速読み取り用にテーブルをバッファリングし、NOCACHE はこの動作を解除します。インデックス構成テーブルでは、この CACHE 動作が提供されます。MONITORING を指定すると、パフォーマンスを高めるためテーブルの統計情報を収集し、NOMONITORING はこの機能を解除します。

 

CREATE TABLE ステートメントでは、INDEX 句は単に、テーブルと共に作成される主キーおよび一意インデックスのために使用します。CREATE TABLE コマンドを使用したインデックスの操作手段の詳細については、Oracle のマニュアルを参照してください。CREATE INDEX コマンドは、ほとんどの目的を果たすために推奨される操作手段です。ただし、Oracle では、主キー制約を持つテーブルを作成する場合、インデックスは自動的に作成されます。こうした状況では、ユーザーがインデックスを作成する必要はありません。

 

PARALLEL 句を使用すると、別個の CPU によってテーブルを並列に作成でき、処理が高速化します。作成後のテーブルに対するクエリーおよびその他のデータ操作処理を並列処理できます。オプションで整数値を指定すると、処理で使用される並列スレッドの数、および将来のテーブルで使用できる並列スレッドの数を定義できます。Oracle では、特定の並列処理で使用する最適スレッド数が計算されるので、この機能は省略可能です。デフォルトは NOPARALLEL です。これによってテーブルは直列に作成され、将来のクエリーおよびデータ操作処理の並列処理が無効となります。

 

DISABLE および ENABLE 句は、テーブルに対する制約をそれぞれ無効または有効にします。基本的に、DISABLE 句は、任意のアクティブな整合性制約やトリガーを無効にできます。反対に、ENABLE は、任意の無効化された整合性制約やトリガーを有効にできます。これらの句の構文を次に示します。

 
DISABLE | ENABLE {{UNIQUE(column[,...n] |
   PRIMARY KEY |
   CONSTRAINT constraint_name}
      [CASCADE]}
      [EXCEPTIONS INTO [owner.]table_name]
      [USING INDEX [INITRANS int][MAXTRANS int]
         [TABLESPACE tablespace_name][storage_characteristics]
         [PCTFREE int] |
 

CASCADE キーワードは、DISABLE 句でのみ使用可能で、カスケード制約やトリガーを無効にしません。代わりに、この句で指定した制約に依存するすべての整合性制約に無効化または有効化を連鎖させます。EXCEPTIONS INTO 句は、ENABLE でのみ使用可能で、すべての整合性制約違反の情報を既存の例外テーブルに格納します。USING INDEX 句も ENABLE でのみ使用可能で、指定インデックス、特に主キーおよび一意キーに対して様々な記憶特性を指定する機構を提供します。デフォルトでは、すべての制約が有効になっています。

 

AS SELECT_statement 句は、有効な SELECT ステートメントからのレコードを新しいテーブルに書き込みます。PostgreSQL の CREATE . . . AS SELECT の実装とは異なり、CREATE TABLE ステートメントの列は、SELECT ステートメント内の列と一致する必要があります。CREATE . . . AS SELECT のロギングは、NOLOGGING キーワードを使用して解除できます。REDO ログファイルへのロギングはデフォルトの動作です。

 

Oracle は多数のオブジェクト指向の機能をサポートしていますが、本マニュアルではその機能については説明しません。

 
PostgreSQL の構文およびバリエーション
 
CREATE [TEMPORARY | TEMP] TABLE table
(column_name datatype [NULL | NOT NULL] [DEFAULT value]
  |[UNIQUE]
  | [PRIMARY KEY (column[,...n])]
   | [CHECK (expression) ]
   | REFERENCES reference_table (reference_column)
        [MATCH {FULL | PARTIAL | default}]
        [ON DELETE {CASCADE | NO ACTION | RESTRICT | SET NULL | SET
           DEFAULT}]
        [ON UPDATE {CASCADE | NO ACTION | RESTRICT | SET NULL | SET
           DEFAULT}]
        [[NOT] DEFERRABLE] [INITIALLY {DEFERRED | IMMEDIATE}] } [,...n]
|[table_constraint][,...n]
[INHERITS (inherited_table [,...n])]

| [ON COMMIT {DELETE | PRESERVE} ROWS]

| AS SELECT_statement
 

PostgreSQL では、MySQL と同じような構文を使用して、一時 (TEMPORARY) テーブルを作成できます。一時テーブルは、一時テーブルが作成されたセッション期間内のみ存在し、セッションが終了すると自動的に削除されます。

 

UNIQUEPRIMARY KEYCHECK などの制約は、基本的に Microsoft SQL Server と同じです。ただし、PostgreSQL 特有の機能として、複数列を使用して列レベルの制約を作成できます。PostgreSQL では標準的なテーブルレベルの制約もサポートしているため、ANSI 規格のアプローチを推奨します。

 

REFERENCES 制約は CHECK 制約に似ていますが、別のテーブルの列の値に対して値を確認する点が異なります。REFERENCES 制約は、FOREIGN KEY 宣言の一部としても使用できます。MATCH オプションには、完全 (FULL)、一部 (PARTIAL)、およびデフォルト (MATCH にはキーワードはありません) を指定できます。FULL を指定した場合は、複数列外部キーのすべての列が、NULL になるか、有効な値を持つ必要があります。デフォルトでは、NULL と値は混在することができます。PARTIAL は有効な構文ですが、サポートされていません。

 

さらに、REFERENCES 句では、ON DELETE または ON UPDATE 参照整合性に対して様々な動作を宣言できます。

 
  • NO ACTION
      外部キー違反の場合は、エラーを表示します (デフォルト)。
  • RESTRICT
      NO ACTION のシノニムです。
  • CASCADE
      参照列の値に被参照列の値を設定します。
  • SET NULL
      参照列の値に NULL を設定します。
  • SET DEFAULT
      宣言された初期設定値を参照列に設定します。また、初期設定値が存在しない場合は NULL を設定します。
 

REFERENCES 句の DEFERRABLE オプションを指定すると、すべての制約をトランザクションの終了時まで延期します。REFERENCES 句のデフォルトの動作は NOT DEFERRABLE です。INITIALLY 句は DEFERRABLE 句に似ています。INITIALLY DEFERRED を指定すると、トランザクションの終了時に制約が確認され、INITIALLY IMMEDIATE (デフォルト) を指定すると、各ステートメントの実行後に制約が確認されます。

 

Microsoft SQL Server 同様、すべての列レベルの制約はテーブルレベルの制約として宣言できます。ただし、FOREIGN KEY 制約は、列レベルの制約としては宣言できず、テーブルレベルの制約としてのみ宣言できます。REFERENCES 句のすべてのオプションは、FOREIGN KEYS 句の一部としてサポートされています。次に構文を示します。

 
[FOREIGN KEY (column[,...n]) REFERENCES...]
 

INHERITS inherited_table 句では、作成するテーブルのすべての列をどのテーブル (複数指定可) から継承するかを指定します。新しく作成されるテーブルは、上位階層のテーブルに添付されている関数も継承します。継承される列が重複している場合、このステートメントは失敗します。

 

PostgreSQL で一時テーブルまたはグローバル一時テーブルを作成する場合、ON COMMIT 句を作成コマンドに追加することもできます。この句は、レコードがテーブルに対してコミットされた後の一時テーブルの動作を制御します。ON COMMIT DELETE ROWS を指定すると、各コミット後に一時テーブルのすべての行が削除されます。これがデフォルトです。ON COMMIT PRESERVE ROWS を指定すると、トランザクションのコミット後も一時テーブルの行が保持されます。

 

AS SELECT_statement 句を使用すると、有効な SELECT ステートメントからのデータを使用してテーブルの作成とデータ挿入を行います。列、データタイプ、または制約は、クエリーから継承されるため、宣言する必要はありません。これは、SELECT . . . INTO の機能に似ていますが、より分かりやすい構文になっています。

 
 

次の例では、テーブルに外部キーを追加します。

 
-- Creating a column-level constraint
CREATE TABLE favorite_books
   (isbn         CHAR(100)    PRIMARY KEY NONCLUSTERED,
   book_name     VARCHAR(40)  UNIQUE,
   category      VARCHAR(40)  NULL,
   subcategory   VARCHAR(40)  NULL,
   pub_date      DATETIME     NOT NULL,
   purchase_date DATETIME     NOT NULL,
      CONSTRAINT fk_categories FOREIGN KEY (category)
         REFERENCES category(cat_name));
 

categories 列の外部キーは、category テーブルの cat_name 列と関連付けられます。この構文は、本マニュアルで示しているすべてのベンダーでサポートされています。同様に、category および subcategory 列の両方を含む複数列キーとして外部キーを宣言することもできます。

 
...
CONSTRAINT fk_categories FOREIGN KEY (category, subcategory)
         REFERENCES category(cat_name, subcat_name));
 

さらに、pubs データベース (jobs および employee テーブル) のより詳細な例を次に 2 つ示します。

 
-- For a Microsoft SQL Server database
CREATE TABLE jobs
   (job_id  SMALLINT IDENTITY(1,1) PRIMARY KEY CLUSTERED,
   job_desc VARCHAR(50) NOT NULL DEFAULT 'New Position',
   min_lvl  TINYINT NOT NULL CHECK (min_lvl >= 10),
   max_lvl  TINYINT NOT NULL CHECK (max_lvl <= 250))

-- For a MySQL  database
CREATE TABLE employee
   (emp_id INT AUTO_INCREMENT CONSTRAINT PK_emp_id PRIMARY KEY,
   fname VARCHAR(20) NOT NULL,
   minit CHAR(1) NULL,
   lname VARCHAR(30) NOT NULL,
   job_id SMALLINT NOT NULL DEFAULT 1
      REFERENCES jobs(job_id),
   job_lvl TINYINT DEFAULT 10,
   pub_id CHAR(4) NOT NULL DEFAULT ('9952')
      REFERENCES publishers(pub_id),
   hire_date DATETIME NOT NULL DEFAULT (CURRENT_DATE(  ));

CREATE TABLE publishers
   (pub_id char(4) NOT NULL
      CONSTRAINT UPKCL_pubind PRIMARY KEY CLUSTERED
      CHECK (pub_id IN ('1389', '0736', '0877', '1622', '1756')
      OR pub_id LIKE '99[0-9][0-9]'),
   pub_name varchar(40) NULL,
   city varchar(20) NULL,
   state char(2) NULL,
   country varchar(30) NULL DEFAULT('USA'))
 

記憶プロパティが多数設定された Oracle の CREATE TABLE ステートメントの例を次に示します。

 
CREATE TABLE classical_music_cds
   (music_id        INT,
   composition      VARCHAR2(50),
   composer         VARCHAR2(50),
   performer        VARCHAR2(50),
   performance_date DATE DEFAULT SYSDATE,
   duration         INT,
   cd_name          VARCHAR2(100),
CONSTRAINT pk_class_cds PRIMARY KEY (music_id)
   USING INDEX TABLESPACE index_ts
   STORAGE (INITIAL 100K NEXT 20K),
CONSTRAINT uq_class_cds UNIQUE (composition, performer, performance_date)
   USING INDEX TABLESPACE index_ts
   STORAGE (INITIAL 100K NEXT 20K))
TABLESPACE tabledata_ts;
 
CREATE TRIGGER 

トリガーは、特殊なストアドプロシージャーで、データ変更ステートメントの実行時に自動的に起動されます。トリガーは、特定のテーブルに対する特定のデータ変更ステートメント (INSERTUPDATE、または DELETE) に関連付けられます。

 
ベンダーコマンド
SQL Server変則対応
MySQL未対応
Oracle変則対応
PostgreSQL変則対応
 
SQL99 の構文および説明
 
CREATE TRIGGER trigger_name
{BEFORE | AFTER} {[DELETE] | [INSERT] | [UPDATE] [OF column [,...n]}
ON table_name
[REFERENCING {OLD [ROW] [AS] old_name | NEW [ROW] [AS] new_name
  OLD TABLE [AS] old_name | NEW TABLE [AS] new_name}]
[FOR EACH { ROW | STATEMENT }]
[WHEN (conditions)]
code block
 

トリガー (trigger_name) は、デフォルトでは、ステートメントレベルで 1 回起動されます。つまり、単一の INSERT ステートメントによってテーブルに 500 行が追加される場合でも、そのテーブルに対する挿入トリガーが起動されるのは 1 度のみです。データ変更処理の各行につき 1 回のトリガーを起動できるベンダーもあります。したがって、テーブル内に 500 行を挿入するステートメントに行レベルの挿入トリガーがあれば、各行が挿入されるたびに 1 回ずつ、計 500 回トリガーが起動されます。

 

トリガーは、指定したテーブル (table_name) に対する特定のデータ変更ステートメント (INSERTUPDATE、または DELETE) に関連付けられるだけでなく、起動する特定のタイミングも設定できます。一般的に、BEFORE を指定すると、トリガーはデータ変更ステートメントの処理前に起動され、AFTER を指定すると、処理後に起動されます。また、INSTEAD OF (ベンダーが対応している場合) を指定すると、そのステートメントの処理の代わりに起動されます。データ変更ステートメントの前、またはそのステートメントの代わりに起動されるトリガーでは、そのステートメントによる変化が分かりませんが、ステートメントの処理後に起動されるトリガーでは、データ変更ステートメントによる変更結果を知ることができるので、その変更に対して動作することもできます。

 
Microsoft SQL Server の構文およびバリエーション
 
CREATE TRIGGER trigger_name
ON {table_name | view_name}
[WITH ENCRYPTION]
{FOR | AFTER | INSTEAD OF} {[DELETE] [,] [INSERT] [,] [UPDATE]}
[WITH APPEND]
[NOT FOR REPLICATION]
AS
  {
  T-SQL_block
  |
  { IF UPDATE(column) [{AND | OR} UPDATE(column)] [...n]
    |
    IF (COLUMNS_UPDATED(  ) {bitwise_operator} updated_bitmask)
    { comparison_operator} column_bitmask [...n] }
    T-SQL_block [...n]
   }
 

Microsoft SQL Server の CREATE TRIGGER ステートメントでは、多数の興味深い機能をサポートしてます。まず、SQL Server では、指定したテーブル (table_name) またはビュー (view_name) に対する 1 つのデータ操作処理に対して複数のトリガー (trigger_name) を設定できます。したがって、1 つのテーブルに対して 3 つの UPDATE トリガーを設定できます。

 

WITH ENCRYPTION 句を使用すると、syscomments システムテーブル内に格納されるトリガーのテキストを暗号化します。WITH APPEND 句を指定すると、既存の種類のトリガーをテーブルまたはビューに追加します。この句は製品の下位互換性を保つためにあり、FOR トリガーでのみ使用できます。NOT FOR REPLICATION 句を指定すると、SQL Server の組み込みレプリケーション機能によって呼び出されるデータ操作処理におけるトリガーを無効にします。

 

FORAFTER、および INSTEAD OF 句は、トリガーの起動時期を指定します。FOR および AFTER キーワードはシノニムで、同じ機能を提供します。これらのキーワードは実際、トリガーを起動するデータ変更ステートメント、カスケード動作および制約確認が正常に完了した後にのみトリガーが起動するよう指定します。1 つのテーブルに対して、複数の AFTER トリガーを指定できます。これらのトリガーの順番は定義されませんが、テーブルで実行される最初と最後の AFTER トリガーは sp_settriggerorder システムストアドプロシージャーを使用して指定できます。

 

AFTER トリガーはビューに対しては定義できません。

 

INSTEAD OF 句は機能的に Oracle の BEFORE トリガーと同じです。この句を指定すると、トリガーを起動するデータ変更ステートメントの前 (つまり、そのステートメントの代わり) にトリガーが起動されますが、特定のテーブルに対する INSERTUPDATE、または DELETE の各ステートメントにつき指定できる INSTEAD OF トリガーは 1 つだけです。AFTER トリガーは複数指定できます。この種のトリガーはビューで使用できますが、WITH CHECK OPTION 句が指定されたビューでは使用できません。INSTEAD OF DELETE トリガーは、削除に関するカスケード動作がある場合は使用できません。

 

DELETEINSERT、および UPDATE は、トリガーを起動するデータ変更ステートメントを指定します。SQL Server では、トリガーの定義においてこれらを複数指定する場合、各オプションをコンマで区切ることによって、自由に組み合わせることができます。複数のオプションを指定する場合、組み合わせ定義の各ステートメントに対して同じコードが実行されます。

 

AS T-SQL_block 句には、データ操作処理が実行されるたびにトリガーによって起動されるプロシージャーコードを含めます。このセクションは、Transact-SQL の BEGIN および END 句で囲む必要があります。従来、このセクションには流れ制御言語がよく使用され、データ変更のタイプと量が検査されていました。

 

SQL Server では、トリガーの起動時に、deleted および inserted の 2 つの重要な疑似テーブルがインスタンス化されます。これらのテーブルは、トリガーが定義されるテーブルと構造が同じです。違いは、deleted テーブルには、データ変更ステートメントが実行される前の古いデータが格納され、実行後のテーブルの新しい値が、inserted テーブルに格納される点です。

 

INSTEAD OF トリガーのみが textntext、または image 型の列にアクセスできます。

 

AS IF UPDATE(column) 句を指定すると、指定列に対する INSERTUPDATE 操作を特別に検査します。別の UPDATE(column) 句を最初の句の後に追加して、複数の列を指定できます。その句の後に Transact-SQL の BEGIN . . . END ブロックを続けて指定すると、条件が整った場合に起動する Transact-SQL 操作を複数定義できます。この句は、機能的に IF . . . THEN . . . ELSE 処理と同じです。

 

AS IF (COLUMNS_UPDATE( )) 句は、AS IF UPDATE( ) 句と同様に、指定列に対する INSERT または UPDATE 操作についてのみ実行されます。これによって、挿入または更新された列を示し、列値を様々な方法で比較するビットごとの操作が可能な varbinary ビットパターンが返されます。比較演算子の等号 (=) は、updated_bitmask に指定した列すべてが変更されたかどうかを確認するのに使用し、指定した列のいずれかが変更されたかどうかを確認するには、大なり記号 (>) 記号を使用します。

 

トリガーは、宣言的な参照整合性の制御によく使用されます。ただし、主キーおよび外部キーの宣言には、CREATE TABLE または ALTER TABLE ステートメントの使用が推奨されます。

 

SQL Server では、トリガーの Transact-SQL ブロック内で、ALTERCREATEDROPDENYGRANTREVOKELOADRESTORERECONFIGURE または TRUNCATE のステートメントを使用できません。さらに、すべての DISK ステートメントや UPDATE STATISTICS コマンドも使用できません。

 

SQL Server ではまた、sp_dboption システムストアドプロシージャーの recursive triggers 設定を使用して、トリガーを再帰的に起動できます。再帰トリガーは、自身のアクションによって再び起動します。たとえば、T1 テーブルの INSERT トリガーが、T1 テーブルに対して INSERT 処理を実行する場合に、再帰処理が実行されます。再帰トリガーの使用には注意が必要なので、この機能はデフォルトで無効となっています。

 

同様に、SQL Server では、最大 32 段階のレベルまでのネストしたトリガーを認めています。ネストしたトリガーのいずれかが ROLLBACK 処理を実行すると、それ以降のトリガーは実行されません。ネストしたトリガーとは、たとえば、T1 テーブルのトリガーが T2 テーブルに対する処理を実行すると、T2 テーブルのトリガーが T3 テーブルに対する処理を実行するというものです。トリガーで無限ループが発生すると、トリガーはキャンセルされます。ネストしたトリガーは、システムストアドプロシージャー sp_configure のネストしたトリガーの設定を使用して有効化されます。ネストしたトリガーが無効に設定されている場合、sp_dboption の recursive triggers 設定にかかわらず、再帰トリガーも無効となります。

 

SQL Server の CREATE ステートメントでは、名前の遅延解決 を認めています。これは、コマンドが、データベースに存在していないデータベースオブジェクトを参照した場合でも処理される機能です。

 
Oracle の構文およびバリエーション
 
CREATE [OR REPLACE] TRIGGER [owner.]trigger_name
{BEFORE | AFTER | INSTEAD OF}
{[DELETE] [OR] [INSERT] [OR] [UPDATE [OF column [,...n] ]] [...n]}
ON {table_name | view_name}
[REFERENCING {OLD [AS] old_name | NEW [AS] new_name}]
[FOR EACH { ROW | STATEMENT }]
[WHEN (conditions)]
PL/SQL block
 

他の標準的な CREATE TRIGGER ステートメント同様、このコマンドは、PL/SQL コードブロックを起動するデータ変更処理 (INSERTUPDATE、または DELETE) および起動するタイミングを指定します。タイミングは、データ変更処理の前 (BEFORE)、後 (AFTER)、または代わり (INSTEAD OF) のいずれかです。UPDATE 処理では、列 (複数列も可) に UPDATE OF を指定して、この指定列が変更された場合にのみ更新トリガー (trigger_name) が起動するように指定できます。

 

Oracle では、テーブルではなく、ビューに対してのみ INSTEAD OF トリガーを起動できます。

 

また、DROP TABLE または SHUTDOWN などの特定のデータベースイベントに対してもトリガーを起動できます。

 

REFERENCING 句では、古い (OLD) テーブルと新しい (NEW) テーブルのそれぞれのバージョンを保持する疑似テーブルの名前 (old_name と new_name) を指定します。SQL Server では、これらの疑似テーブルは自動的に inserted および deleted と名付けられます。Oracle では、これらの疑似テーブルのデフォルト名はそれぞれ OLD および NEW です。これらの疑似テーブルは、データ操作処理によって変更される前のレコード値 (OLD 疑似テーブルの値)、および、データ操作処理後の値 (NEW 疑似テーブルの値) と比較されます。疑似テーブルは、PL/SQL_block での条件操作も実行できます。

 

OLD および NEW 疑似テーブルの値を参照する場合、値の前にコロン (:) を付ける必要があります。ただし、トリガーの WHEN 句内ではコロンは使用されません。

 

FOR EACH ROW 句を指定すると、トリガーは、ステートメントトリガーとして暗黙的に起動 (トランザクション全体に対して 1 回起動) されずに、個々の行に対して起動 (処理によって影響を受ける各行ごとに 1 回起動) されます。WHEN 句には、トリガーの実行を条件が満たされた場合のみに制限する SQL の条件 (conditions) を指定します。また、WHEN 句を使用すると、OLD および NEW テーブルを、これらのテーブルを比較する PL/SQL ブロックを構築せずに比較できます。

 

同じテーブルの同じレベル (行レベルまたはステートメントレベル) に対する複数の種類のトリガーを、1 つのトリガーコマンドに結合できます。トリガーを 1 つのステートメントに結合する場合、IF INSERTING THENIF UPDATING THEN、および IF DELETING THEN 句を PL/SQL ブロック内で使用して、コードロジックを別個のセグメントに分割できます。この構造内で、ELSE 句を使用することもできます。

 
PostgreSQL の構文およびバリエーション
 
CREATE TRIGGER trigger_name
{ BEFORE | AFTER }
{ {[DELETE] [OR | ,] [INSERT] [OR | ,] [UPDATE]} [OR ...] }
ON table_name
FOR EACH { ROW | STATEMENT }
EXECUTE PROCEDURE function_name (parameters)
 

PostgreSQL の CREATE TRIGGER 機能の実装は、その他のベンダーと類似しています。BEFORE を指定すると、レコードに対するデータ変更処理の実行前、および、任意の制約の確認前にトリガー (trigger_name) を起動できます。また、AFTER を指定すると、データ操作処理の実行後 (および制約の確認後) にトリガーを起動でき、トランザクションで行われるすべての処理がトリガーに可視となります。

 

Oracle および SQL Server のようにプロシージャー型コードブロックを処理するのではなく、PostgreSQL では、CREATE FUNCTION を使用して作成した関数を、EXECUTE PROCEDURE 句で実行します。また、他のベンダーでは、トリガーはトランザクションのすべての行に対して暗黙的に処理されますが、PostgreSQL では、各行に対してトリガーを実行する場合は FOR EACH ROW 句を使用し、トランザクション全体に対してトリガーを 1 回だけ実行する場合は FOR EACH STATEMENT 句を使用します。

 
 

PostgreSQL の BEFORE トリガーの例を次に示します。このトリガーは、sales テーブルの行を挿入または更新する前に、指定された流通業者 (distributor) ID が distributors テーブルに存在することを行レベルで確認します。

 
CREATE TRIGGER if_dist_exists
BEFORE INSERT OR UPDATE ON sales
FOR EACH ROW
EXECUTE PROCEDURE check_primary_key ('did', 'distributors', 'did');
 

BEFORE トリガーは、データ変更処理によって影響を受けるレコードが、テーブル内で変更される前に処理されるため、データ変更処理によってテーブルにコミットされた値を変更します。AFTER トリガーは、テーブル内で行が変更されるまで起動できないので、検査プロセスによく使用されます。INSTEAD OF は、ユーザーがトランザクションに提供したコードを実行するので、データ変更処理は完全に省略されます。

 

値の比較に OLD および NEW 疑似テーブルを使用する Oracle の BEFORE トリガーの例を次に示します。SQL Server では、DELETED および INSERTED 疑似テーブルを同じ方法で比較に使用します。次のトリガーでは、従業員の給与レコードを変更する前に監査レコードを作成します。

 
CREATE TRIGGER if_emp_changes
BEFORE DELETE OR UPDATE ON employee
FOR EACH ROW
WHEN (new.emp_salary <> old.emp_salary)
BEGIN
  INSERT INTO employee_audit
  VALUES ('old', :old.emp_id, :old.emp_salary, :old.emp_ssn);
END;
 

次の例では、IF DELETING THEN 句を使用する Oracle の挿入トリガーと更新トリガーを構築します。

 
CREATE TRIGGER if_emp_changes
BEFORE DELETE OR UPDATE ON employee
FOR EACH ROW
BEGIN
  IF DELETING THEN
    INSERT INTO employee_audit
    VALUES ('DELETED', :old.emp_id, :old.emp_salary, :old.emp_ssn);
  ELSE
    INSERT INTO employee_audit
    VALUES ('UPDATED', :old.emp_id, :new.emp_salary, :old.emp_ssn);
  END IF;
END;
 

次の SQL Server の例では、contractor という新しいテーブルをデータベースに追加します。また、employee テーブルの従業員が契約者であることを示す全レコードを、contractor テーブルに移動します。employee テーブルに挿入されるはずであったすべての新しい従業員は、INSTEAD OF トリガーを介して contractor テーブルに挿入されます。

 
CREATE TRIGGER if_emp_is_contractor
INSTEAD OF INSERT ON employee
BEGIN
  INSERT INTO contractor
  SELECT * FROM inserted WHERE status = 'CON'

  INSERT INTO employee
  SELECT * FROM inserted WHERE status = 'FTE'
END
GO
 
CREATE VIEW 

この ステートメントは、ビューを作成します。ビューは仮想テーブルとも呼ばれます。ビューはテーブルと同じように動作しますが、実際はクエリーとして定義されます。有効な SELECT ステートメントはほぼすべて、ビューの内容を定義できますが、ORDER BY 句は通常は使用できません。

 

ビューをステートメントで参照すると、そのステートメントが実行されている間、クエリーの結果セットがビューの内容となります。ビューを更新できる場合があり、その変更は基本テーブルの基底データに反映されます。

 
ベンダーコマンド
SQL Server変則対応
MySQL未対応
Oracle変則対応
PostgreSQL変則対応
 

ビューは他のビューから構築することもできますが、これは推奨される方法ではないため、通常は行わないでください。

 
SQL99 の構文および説明
 
CREATE VIEW view_name [(column list)]
AS
(SELECT_statement
[WITH [CASCADED | LOCAL] CHECK OPTION] )
 

ビューの効率は通常、ベースとなっているクエリーと同じです。したがって、定義する SELECT ステートメント (SELECT_statement) が高速で、よく記述されていることが重要になります。

 

ビュー名の後には列リスト (column list) も指定できます。オプションの列リストには、SELECT ステートメントの結果セットにおける各要素のエイリアスを指定します。

 

WITH CHECK OPTION 句は、基本テーブルの更新を認めるビューにおいてのみ使用します。これを指定すると、ビューによって読み取られるデータだけが、ビューによって挿入、更新、または、削除できます。たとえば、employees テーブルのビューが、フルタイムの従業員列のみを表示し、パートタイムの従業員列を表示していない場合、パートタイムの従業員列のデータをそのビューから挿入、更新、または削除することはできません。ネストしたビューには、CHECK OPTION 句の CASCADE および LOCAL オプションを使用します。CASCADE オプションを指定すると、現在のビューおよび構築元のすべてのビューの整合性が確認されます。LOCAL オプションを指定すると、現在のビューが他のビューから構築されている場合でも、現在のビューの整合性しか確認しません。

 

ANSI SQL99 のビューは、次の条件を満たす場合に、ベースとなる基本テーブルを更新できます。

 
  1. SELECT ステートメントを 1 つのテーブルから定義している。
  2. ビュー内に UNIONMINUS、または INTERSECT 演算子がない。
  3. SELECT ステートメントの定義内に、GROUP BY または HAVING 句がない。
  4. SELECT ステートメントの定義内に、ROWNUM または ROWGUIDCOL など、疑似列に対する参照がない。
  5. SELECT ステートメントの定義内にグループ関数がない。
  6. SELECT ステートメントの定義内に DISTINCT 句がない。
 
Microsoft SQL Server の構文およびバリエーション
 
CREATE [owner_name.]VIEW view_name [(column [,...n])]
[WITH {ENCRYPTION | SCHEMABINDING | VIEW_METADATA} [,...n]]
AS
select_statement
[WITH CHECK OPTION]
 

Microsoft SQL Server では、SQL99 にない、ENCRYPTION および SCHEMABINDING の 2 つの新しいオプションを使用できます。ENCRYPTION オプションを指定すると、syscomments テーブル内のビュー (view_name) のテキストが暗号化されます。SCHEMABINDING オプションを指定すると、ビューが特定のスキーマにバインドされます。つまり、ビュー内のオブジェクトを参照するには、フルネーム (所有者とオブジェクト名の両方) を指定する必要があります。SCHEMABINDING を指定して作成したビュー (およびこれらのビューによって参照されるテーブル) を削除または変更するには、ALTER VIEW を使用してスキーマバインディングを削除する必要があります。VIEW_METADATA を指定すると、基本テーブルではなくビューに関するメタデータを、SQL Server が DBLIB および OLEDB API からの呼び出しに返します。VIEW_METADATA で作成または変更されたビューの列は、INSERT および UPDATE INSTEAD OF トリガーで更新できます。

 

SQL Server ではビューにインデックスを作成できます (CREATE INDEX 参照)。ビューに一意の、クラスターインデックスを作成することにより、SQL Server は実質的にビューの物理コピーをデータベースに格納します。基本テーブルを変更すると、インデックスビューも自動的に更新されます。

 

インデックスビューは、基本テーブルに対して、SCHEMABINDING 句のみを使用して作成します。これは高度な技法であるため、熟練プログラマーによってのみ使われます。この技法の詳細については、ベンダーのマニュアルを参照してください。

 
Oracle の構文およびバリエーション
 
CREATE [OR REPLACE] [FORCE | NO FORCE] VIEW [owner_name.]view_name
  [(column [,...n])]
AS
SELECT_statement
[WITH [READ ONLY | CHECK OPTION [CONSTRAINT constraint_name] ] ]
 

OR REPLACE 句は、同じ名前を持つあらゆる既存のビューを新しいビューに置換します。FORCE 句を指定すると、基本テーブルが存在するかどうか、またはビューを作成するユーザーが基本テーブルに対する権限を所有しているかどうかにかかわらず、ビューを作成します。NO FORCE 句は、基本テーブルが存在し、適切な権限がある場合に限り、ビューを作成します。

 

Oracle では、CHECK OPTION を使用でき、さらに CONSTRAINT 句を使用して制約の名前 (constraint_name) を指定できます。CHECK OPTION 句はネストしたビューで使用できますが、トップレベルビューの CHECK OPTION が有効な場合に限られます。制約の名前を省略すると、Oracle が新たに SYS_Cn という名前を付けます。n は整数です。

 

Oracle では、SQL99 要件を満たし、追加された要件にどのような式も含まれない場合に、ビューを介してデータ操作処理を実行できます。WITH READ ONLY 句を指定すると、ビューはデータの取得にのみ使用されます。

 
PostgreSQL の構文およびバリエーション
 
CREATE VIEW view_name AS SELECT_statement
 

PostgreSQL の CREATE VIEW は、他のベンダーが対応している一部の複雑なオプションには対応していません。ただし、テーブルおよび他の定義済みクラスオブジェクトに基づいてビューを作成できます。PostgreSQL のビューは、通常、他のビューではなく、他のテーブルに基づいてのみ作成され、基底の基本テーブルのデータ変更には使用されません。

 
 

単一のテーブルの全内容に基づく最もシンプルなビューの例を次に示します。

 
CREATE VIEW employees
AS
SELECT *
FROM employee_tbl;
 

この例では、カリフォルニア (California) 州の著者 (authors) にのみ適用されるデータ変更を可能とする california_authors ビューを示します。

 
CREATE VIEW california_authors
AS
SELECT au_lname, au_fname, city, state
FROM authors
WHERE state = 'CA'
WITH CHECK OPTION
GO
 
DECLARE CURSOR 

DECLARE CURSOR コマンドを使用すると、テーブルから一度に 1 行ずつレコードの取得および操作を行うことができます。これによって、従来の SQL が提供していた集合処理ではなく、行単位の処理が行われます。この処理を正しく行うには、次のことを行う必要があります。

 
  1. カーソルを宣言する (DECLARE)
  2. カーソルを開く (OPEN)
  3. カーソルから行を取得する (FETCH)
  4. 終了後、カーソルを閉じる (CLOSE)
 

MySQL は ANSI SQL スタイルのサーバーサイドカーソルには対応していませんが、同じ機能を提供する広範な C プログラミング拡張には対応しています。

 
ベンダーコマンド
SQL Server対応
MySQL未対応
Oracle対応
PostgreSQL対応
 
SQL99 の構文および説明
 

DECLARE CURSOR コマンドは、SELECT ステートメントを指定することによって機能します。SELECT ステートメントによって返される各行は、個々に取得および操作されます。DECLARE CURSOR コマンドは、サーバーサイドカーソルの特性も定義します。特性には、カーソルのスクロール方法、および SELECT ステートメントが結果セットを取得する方法が含まれます。

 

Microsoft SQL Server では、INSENSITIVE および SCROLL オプションが識別されます。INSENSITIVE キーワードを指定すると、カーソルは、カーソルによって使われる結果セットの一時コピーを作成します。カーソルに対するすべてのリクエストに対しては、基本テーブルからではなく、一時テーブルから答えが返されます。カーソルでは変更が認められていません。以降のカーソルによる取り出しは、カーソルによって行われたすべての変更を反映しません。SCROLL キーワードは、カーソルに対するすべての FETCH オプション (FIRSTLASTPRIORNEXTRELATIVE、および ABSOLUTE) を有効にします。詳細については、FETCH コマンドの項を参照してください。SCROLL を宣言しない場合、FETCH のオプションとして使用できるのは、NEXT だけです。FOR READ ONLY 句を使用して、読み取り専用のカーソルを宣言することもできます。

 

Oracle では、最初に変数を宣言していない限り、SELECT ステートメントの WHERE 句内で変数を使用できません。DECLARE ではパラメータを割り当てられませんが、代わりに、OPEN コマンドでパラメータを割り当てられます。

 

PostgreSQL の実装は、Microsoft SQL Server と非常に似ていますが、BINARY オプションが使用できる点が異なります。BINARY を指定すると、カーソルはテキスト形式のデータではなく、バイナリ形式のデータを取得します。

 
Microsoft SQL Server の構文
 
DECLARE cursor_name [INSENSITIVE] [SCROLL] CURSOR
FOR select_statement
[FOR {READ ONLY | UPDATE [OF column_name [,...n]]}]
 
Oracle の構文
 
DECLARE CURSOR cursor_name [parameter1 datatype1 [,...parameterN datatypeN]
IS select_statement
[FOR UPDATE [OF column_name [,...n]]}]
 
PostgreSQL の構文
 
DECLARE cursor_name [BINARY] [INSENSITIVE] [SCROLL] CURSOR
FOR select_statement
[FOR {READ ONLY | UPDATE [OF column_name [,...n]]}]
 
Microsoft SQL Server の構文およびバリエーション
 

Microsoft SQL Server では本章で前述した標準的なフォーマットに対応していますが、より複雑な拡張機能も用意しています。構文を次に示します。

 
DECLARE cursor_name CURSOR
[LOCAL | GLOBAL] [FORWARD_ONLY | SCROLL]
[STATIC | KEYSET | DYNAMIC | FAST_FORWARD]
[READ_ONLY | SCROLL_LOCKS | OPTIMISTIC]
[TYPE_WARNING]
FOR select_statement
[FOR UPDATE [OF column_name [,...n]]]
 

この構文は、ANSI 規格のカーソル宣言と同じ方法で機能しますが、新しい機能を多数提供しています。まず、カーソル (cursor_name) の有効範囲を LOCAL または GLOBAL として宣言できます。LOCAL を宣言した場合、カーソルは、宣言された現行の Transact-SQL のバッチ、ストアドプロシージャー、またはトリガーの中でしか使用できません。GLOBAL を宣言した場合、カーソルは、接続を通じて OPEN および FETCH コマンドで利用できます。

 

Transact-SQL の表記を、Microsoft SQL Server の ANSI 規格のカーソル宣言と混同しないでください。

 

次のいくつかのオプションを使用すると、カーソルがレコードセット内を検索する方法を決めることができます。FORWARD_ONLY は、SCROLL とは逆に、カーソルが最初のレコードから最後のレコード方向にしかスクロールできないように指定します。これを、STATICKEYSET、または DYNAMIC と共に使用することはできません。これは DYNAMIC カーソルとして機能します。

 

STATIC の機能は、INSENSITIVE キーワードと類似しています。KEYSET は、STATIC および INSENSITIVE と似ていますが、結果セットを変更できる点が異なります。キーセットは、いったんカーソルが開いてから他のユーザーが挿入したレコードについては関知しません。しかし、他のユーザーが削除したレコードについては、@@FETCH_STATUS が -2 となります。新しい値は、WHERE CURRENT OF を指定することによって、更新が完了すると参照できるようになります。DYNAMIC は、カーソルを使用した処理中に結果セットに対して行ったすべてのデータ変更を反映します。結果セットは、FETCH の処理中にも変更できます。FETCH ABSOLUTE は、DYNAMIC カーソルではサポートされていません。FAST_FORWARD は、FORWARD_ONLYREAD_ONLY の省略表現ですが、付加的な機能もあります。FAST_FORWARD は、SCROLLFOR_UPDATESCROLL_LOCKSOPTIMISTIC、および FORWARD_ONLY と相互に排他的です。

 

READ_ONLY には他に、SCROLL_LOCKS および OPTIMISTIC のオプションが使用できます。SCROLL_LOCKS は、新しいレコードを取り込むと必ずレコードレベルのロックを強制し、カーソルを介した更新と削除を正しく行うようにします。OPTIMISTIC は、カーソルを介して場所を指定した更新と削除が、別のユーザーが行を変更した場合には失敗するようにします。

 

最後に、TYPE_WARNING オプションは、KEYSET から DYNAMIC のように型が変更されると、SQL Server がクライアントに警告メッセージを送信するようにします。

 
 

次の Microsoft SQL Server のシンプルな例では、publishers テーブルのカーソルを宣言して開きます。カーソルは publishers テーブルから SELECT ステートメントに一致する最初のレコードを取得し、別のテーブルにその値を挿入します。そして、すべてのレコードが処理されるまで、順次、次のレコードを処理します。最後に、カーソルを閉じ、解放 (DEALLOCATE) します。DEALLOCATE は Microsoft SQL Server でのみ使用されます。

 
DECLARE @publisher_name VARCHAR(20)

DECLARE pub_cursor CURSOR
FOR SELECT pub_name FROM publishers
    WHERE country <> 'USA'

OPEN pub_cursor
FETCH NEXT FROM pub_cursor INTO @publisher_name
WHILE @@FETCH_STATUS = 0
BEGIN
    INSERT INTO foreign_publishers VALUES(@publisher_name)
END

CLOSE pub_cursor
DEALLOCATE pub_cursor
 

次の Oracle の例では、カーソルを他の変数と共に宣言ブロックで宣言し、カーソルの残りの部分はその後で処理します。

 
DECLARE
   new_price NUMBER(10,2);
   CURSOR title_price_cursor IS
      SELECT title, price
      FROM titles
      WHERE price IS NOT NULL;
   title_price_val title_price_cursor%ROWTYPE;
BEGIN
   OPEN title_price_cursor;
   FETCH title_price_cursor INTO title_price_val;
   new_price := "title_price_val.price" * 1.25
   INSERT INTO new_title_price VALUES (title_price_val.title, new_price)
   CLOSE title_price_cursor;
END;
 

この例では PL/SQL を多用していますが、コードのほとんどは、本マニュアルでは説明していません。ただし、DECLARE ブロックでカーソルを宣言していることは明らかです。PL/SQL の実行ブロックでは、OPEN コマンドでカーソルを初期化し、FETCH コマンドで値を取得し、最後に CLOSE コマンドでカーソルを閉じます。

 
DELETE 

DELETE ステートメントは、指定したテーブルからレコードを消去します。この処理はログに記録されます。つまり、ROLLBACK コマンドを使用して取り消すことができます。

 
ベンダーコマンド
SQL Server変則対応
MySQL変則対応
Oracle対応
PostgreSQL対応
 

DELETE ステートメントを WHERE 句なしで使用することはあまりありません。WHERE 句を使用しないと、影響を受けるテーブルからすべての行が削除されるからです。

 
SQL99 の構文および説明
 
DELETE [FROM] [owner.]table_name [WHERE clause]
 

テーブルの中のすべての行を削除する必要がある場合は、TRUNCATE TABLE ステートメントの使用を推奨します。このコマンドに対応しているデータベースでは、すべての行を物理的に削除するには、通常、このコマンドを使用したほうがすばやく行えます。TRUNCATE TABLEDELETE より速いのは、TRUNCATE がログに記録されないためで、ロールバックも不可能です。ロギングのオーバーヘッドを省くことによって、多数のレコードを削除する際に時間を大幅に節約できます。

 
Microsoft SQL Server の構文およびバリエーション
 
DELETE [FROM] [owner.] {table_name | view_name}
[WITH (query_hint[,...n]]
[FROM table_source[,...n]]
[WHERE clause | [CURRENT OF [GLOBAL] cursor_name]]
[OPTION (query_hint[,...n])]
 

Microsoft SQL Server では、テーブル (table_name)、および単一のテーブルを記述するビュー (view_name) の両方からレコードを削除できます。複数のビューから削除を行うためには、他にいくつかの特別な規則がありますが、それらは非常に複雑なため本マニュアルでは説明しません。最初の FROM の直後とステートメントの最後の 2 か所で、SQL Server のデフォルトのオプティマイザによる動作を無効にできますが、これは熟練者のみが行うようにしてください。これらのヒント (query_hint) は ANSI 規格には含まれていませんが、ほとんどのベンダーのマニュアルには含まれています。

 

さらに、SQL Server では、2 つ目の FROM 句を使用できます。2 つ目の FROM 句では、JOIN ステートメントを使用できるので、最初の FROM のテーブル (table_name) から、2 つ目の FROM で宣言されたテーブルの行に基づいて、非常に簡単に行を削除できます。

 

WHERE CURRENT OF 句は、カーソルで位置決めして削除を行うために使用します。カーソルと共に使用することにより、この形式の DELETE は現在カーソルが開いている行のみを消去します。

 
MySQL の構文およびバリエーション
 
DELETE [LOW_PRIORITY] FROM table_name [WHERE clause] [LIMIT rows]
 

MySQL はスピードが最適化されています。したがって、MySQL では、LOW PRIORITY を指定でき、テーブルを読むクライアントが他にいなくなるまで、DELETE の実行を遅延します。また、MySQL では、LIMIT rows 句を使用して、制御をクライアントに返すまでに削除するレコード数の上限を任意に設定できます。

 
Oracle の構文およびバリエーション
 
DELETE FROM [schema.]{table_name | view_name | snapshot_name}
   {PARTITION (partition_name) | SUBPARTITION (subpartition_name)} |
[WHERE clause]
[subquery WITH {READ ONLY | CHECK OPTION [CONSTRAINT constraint_name]} ]
[RETURNING expression[,...] INTO variable[,...]
 

Oracle では、テーブル (table_name)、ビュー (view_name)、およびパーティション化されたビューとテーブル (snapshot_name) から行を削除できます。

 

PARTITION および SUBPARTITION は、削除するテーブル内のパーティション (partition_name)、またはサブパーティションの名前 (subpartition_name) を指定します。

 

WITH 句はサブクエリーと共に使用します。これは、DELETE ステートメントのアクションを制限します。WITH READ ONLY オプションを指定すると、コマンド内で使用するすべてのサブクエリーは更新されません。WITH CHECK OPTION を指定すると、サブクエリーに含まれないすべての行を削除 (DELETE) できます。

 

RETURNING は、コマンドの影響を受ける行を取得します。単一行の削除に使用した場合、その行の値は PL/SQL 変数およびバインド変数に格納されます。複数行の削除に使用した場合、それらの行の値はバインド配列に格納されます。INTO キーワードを指定すると、削除された値が変数リストに格納されます。

 
PostgreSQL の構文およびバリエーション
 
DELETE FROM [ONLY] table
[WHERE {clause | CURRENT OF cursor_name}]
 

PostgreSQL では、テーブルから行および定義済みサブクラスを削除するのに DELETE コマンドを使用します。指定テーブルからのみ行を削除する場合、ONLY 句を使用します。WHERE CURRENT OF 句を指定すると、現在開かれている指定のオープンカーソルの行のみが削除されます。

 
 

titles テーブルのすべてのレコードを削除するには次のようにします。

 
DELETE titles
 

authors テーブル内の "Mc" で始まる名字 (au_lname) のレコードをすべて削除するには次のようにします。

 
DELETE FROM authors
WHERE au_lname LIKE 'Mc%'
 

古い ID 番号 (title_id >= 40) を持つすべてのタイトル (titles) を削除するには次のようにします。

 
DELETE titles WHERE title_id >= 40
 

売上のない (ytd_sales IS NULL) すべてのタイトル (titles) を削除するには、次のようにします。

 
DELETE titles WHERE ytd_sales IS NULL
 

別のテーブルに対するサブクエリーの結果に基づいて、あるテーブルのレコードを削除するには、次のようなコマンドを実行します。次のケースでは、titles テーブルで "computers" という文字を含むレコードを検索し、そのレコードを titleauthor テーブルから削除します。

 
DELETE FROM titleauthor
WHERE title_id IN
  (SELECT title_id
  FROM titles
  WHERE title LIKE '%computers%')
 
DISCONNECT 

DISCONNECT ステートメントは DBMS への接続を終了します。

 
ベンダーコマンド
SQL Server制限付き対応
MySQL未対応
Oracle変則対応
PostgreSQL未対応
 
SQL99 の構文および説明
 
DISCONNECT {CURRENT | ALL | connection_name}
 

このコマンドは、現行の SQL プロセスとデータベースサーバーとの間で確立されている接続を終了します。CURRENT 句は現在アクティブなユーザー接続を閉じます。ALL 句は現在のユーザーが開いているすべての接続を閉じます。また、指定した接続のみを閉じることもできます。

 
Microsoft SQL Server の構文およびバリエーション
 

Microsoft SQL Server は、Embedded-SQL (ESQL) でのみ DISCONNECT をサポートし、その検索ツールの SQL Query Analyzer ではサポートしていません。ESQL では SQL99 の構文を完全にサポートしています。ESQL プログラムで Microsoft SQL Server から接続を閉じる場合、データベースサーバーとの接続を完全に切断するために DISCONNECT ALL コマンドを使用する必要があります。

 
Oracle の構文およびバリエーション
 
DISC[ONNECT]
 

SQL Server とは対照的に、Oracle では、その検索ツールの SQL*Plus でのみDISCONNECT を使用できます。Oracle のこのコマンドは、データベースサーバーとの現行のセッションは終了しますが、SQL*Plus での作業は続行できます。たとえば、プログラマーは、バッファの編集や実行ファイルの保存などを続行できます。ただし、SQL コマンドを発行するには再接続を確立する必要があります。SQL*Plus を終了し、ファイルシステムへ戻るには、EXIT または QUIT コマンドを使用する必要があります。

 

Oracle ではまた、ALTER SYSTEM DISCONNECT SESSION でこの機能をサポートしています。ただし、これは DBA がデータベースとのセッション (通常、異常のあるセッション) を強制的に切断するための特権的なコマンドです。

 
PostgreSQL
 

PostgreSQL では、DISCONNECT コマンドを明示的にサポートしていません。ただし、各プログラミングインターフェイスでは切断処理をサポートしています。たとえば、Server Programming Interface では、SPI_FINISH を使用でき、PL/tcl プログラミングパッケージでは、PG_CONNECT を使用できます。

 
 

Oracle サーバーとの現行の接続を終了します。

 
DISCONNECT;
 

Microsoft SQL Server では、ESQL プログラムでのみ DISCONNECT をサポートしています。

 
EXEC SQL DISCONNECT new_york;
 
DROP DATABASE 

DROP DATABASE は、CREATE DATABASE コマンドで行ったすべての作業を取り消します。このコマンドは、既存のデータベースオブジェクトをすべて削除し、それらのデータベースオブジェクトが使用していた領域を解放します。ほとんどのベンダーでは、ユーザー (所有者を含む) が削除対象のデータベース内でアクティブである限り、このコマンドを実行できません。

 
ベンダーコマンド
SQL Server対応
MySQL対応
Oracle未対応
PostgreSQL対応
 
SQL99 の構文および説明
 
DROP DATABASE database_name
 

CREATE DATABASE 同様、DROP DATABASE は、ANSI SQL では主要なコマンドではなく、拡張コマンドとしてのみサポートされています。SQL99 では、ほとんどの実装で "データベース" の問題として考えられている領域をカバーするため、SCHEMA および DOMAIN に関連するコマンドが優先されます。

 

データベースベンダーによって作成されたシステムデータベースは決して削除しないでください。データベースの所有者またはシステム管理者以外がデータベースを削除するには、明示的な許可が必要です。

 
Microsoft SQL Server の構文およびバリエーション
 
DROP DATABASE database_name [,...n]
 

SQL Server では、各データベース名をコンマで区切ることにより、1 つのコマンドで複数のデータベースを削除できます。マスターデータベース内のユーザー、sys admin 権限を持つユーザー、またはデータベースの所有者のみがデータベースを削除できます。削除されるデータベースは、ONLINE である必要があります。

 
MySQL と PostgreSQL の構文およびバリエーション
 

MySQL および PostgreSQL でのこのコマンドは、データベース全体とすべての関連ファイルを削除します。データベースは、削除されたファイル数を示すメッセージを送信します。PostgreSQL の実装では、開いているデータベース、および使用されているデータベースは削除できません。

 
Oracle の構文およびバリエーション
 

Oracle では DROP DATABASE をサポートしていません。削除するデータベースと同じ名前を指定して、パラメータなしでコマンド CREATE DATABASE database_name を発行すれば、そのデータベースを削除できます。

 
DROP FUNCTION  

このコマンドは、現行のデータベースからユーザー定義関数を削除します。

 
ベンダーコマンド
SQL Server変則対応
MySQL変則対応
Oracle変則対応
PostgreSQL変則対応
 
SQL99 の構文および説明
 
DROP FUNCTION function_name {RESTRICT | CASCADE}
 

このコマンドは関数 (funstion_name) を恒久的に削除します。RESTRICT 句は、ビューなどのその他のデータベースオブジェクトが削除対象の関数に依存している場合に、このコマンドが失敗するようにします。反対に、CASCADE オプションを指定すると、関数、関数の権限、および関数に依存するデータベースオブジェクトを削除します。

 
Microsoft SQL Server の構文およびバリエーション
 
DROP FUNCTION [owner_name.]function_name [,...n]
 

SQL Server の他の DROP コマンド同様、各データベースオブジェクト名を、コンマで区切って指定することで、同じ型のデータベースオブジェクトを複数削除できます。

 
MySQL の構文およびバリエーション
 

このコマンドは関数を含むファイルを実際には削除しません。代わりに、システムテーブルから関数参照を削除します。削除した関数参照は CREATE FUNCTION ステートメントを使用して再び追加できます。

 
Oracle の構文およびバリエーション
 
DROP FUNCTION [owner_name.]function_name
 

Oracle の他の DROP コマンド同様、関数の所有者の名前 (owner_name) を指定できます。所有者の名前を指定しない場合は、現行のユーザーと見なされ、現行ユーザーの所有する関数のみが削除されます。また、ユーザーに DROP ANY FUNCTION システム権限があれば、あらゆる場所のすべての関数を削除できます。

 
PostgreSQL の構文およびバリエーション
 
DROP FUNCTION name ( [ type [,...n] ] )
 

PostgreSQL では、どのようなプログラミング言語で宣言された関数でも削除できます。type は削除する関数の入力引数です。type は指定する必要があります。これは、指定した名前とパラメータの型を持つ関数のみを削除するためです。

 
DROP INDEX 

DROP INDEX コマンドは、現行のデータベース内のインデックスを削除します。インデックスを削除すると、それまでインデックスに消費されていたすべての領域が直ちに解放されます。ただし、DROP INDEX は、PRIMARY KEY または UNIQUE 制約を削除しません。これらを削除するには、ALTER TABLE . . . DROP コマンドを使用する必要があります。主キーまたは一意制約の詳細については、CREATE TABLE コマンドの項を参照してください。

 
ベンダーコマンド
SQL Server変則対応
MySQL変則対応
Oracle変則対応
PostgreSQL変則対応
 
SQL99 の構文および説明
 
DROP INDEX table_name.index_name
 

PostgreSQL は SQL99 標準に従っていますが、相違点があります。

 
Microsoft SQL Server の構文およびバリエーション
 
DROP INDEX {table_name | view_name}.index_name [,...n]
 

Microsoft SQL Server では、テーブル (table_name) およびビュー (view_name) のどちらで作成されたインデックス (index_name) も削除できます。非クラスターインデックスを含むテーブルのクラスターインデックスを削除すると、すべての非クラスターインデックスが再構築され、新しいポインタが割り当てられます。

 
MySQL の構文およびバリエーション
 
DROP INDEX table_name.index_name [,...n]
 

MySQL の古いバージョンでは、互換性を保つためだけにこのコマンドが含まれていますが、新しいバージョンでは、指定したインデックスが実際に削除されます。このステートメントは機能的に、MySQL の ALTER TABLE . . . DROP INDEX ステートメントと同じです。

 

MySQL では、テーブル名とインデックス名の各組をコンマで区切ることによって、複数のインデックスを削除できます。

 
Oracle の構文およびバリエーション
 
DROP INDEX [owner_name.]index_name
 

Oracle では、インデックスの削除にテーブル名を指定せず、インデックス名 (index_name) を直接指定します。また、所有者の名前 (owner_name) を基にインデックスを削除することもできます。

 
DROP PROCEDURE  

このコマンドは、現行のユーザーデータベース内の既存のストアドプロシージャーを削除します。

 
ベンダーコマンド
SQL Server対応
MySQL未対応
Oracle対応
PostgreSQL未対応
 
SQL99 の構文および説明
 
DROP PROCEDURE procedure_name {RESTRICT | CASCADE}
 

このコマンドは、基本的に DROP FUNCTION と同じですが、関数ではなく、ストアドプロシージャーを削除する点が異なります。

 
Microsoft SQL Server の構文およびバリエーション
 
DROP PROCEDURE [owner_name.]procedure_name [,...n]
 

Microsoft SQL Server では、各ストアドプロシージャーの名前をコンマで区切ることによって、複数のストアドプロシージャーを削除できます。特定のバージョンのストアドプロシージャーのみを削除することはできません。同じバージョングループのストアドプロシージャーが削除されます。

 
Oracle の構文およびバリエーション
 
DROP PROCEDURE [owner_name.]procedure_name
 

Oracle では、プロシージャーの削除に所有者の名前 (owner_name) も指定できます。DROP ANY PROCEDURE システム権限を持つユーザーは、他のユーザーが所有するプロシージャーを削除できます。

 
DROP ROLE 

このコマンドは、現行ユーザーデータベースで、指定したユーザー権限セットを削除できます。

 
ベンダーコマンド
SQL Server未対応
MySQL未対応
Oracle変則対応
PostgreSQL未対応
 
SQL99 の構文および説明
 
DROP ROLE role_name
 

DROP ROLE コマンドは、指定したロール (role_name) を削除します。WITH ADMIN OPTION 権限のあるユーザーのみがロールを削除できます。

 
Oracle の構文
 
DROP ROLE [owner_name.]role_name;
 

DROP ROLE コマンドを実行すると、現行ユーザーデータベースのロール (role_name) が削除されます。一度削除すると、それまでそのロールを割り当てられていたユーザーやロールからは一切使用することができません。

 
DROP TABLE 

このコマンドは、削除するテーブルのテーブル定義、すべてのデータ、インデックス、トリガー、制約、および権限指定も削除します。削除したテーブルを参照するビューやストアドプロシージャーはすべて、明示的に変更するか削除されない限り、問題に直面することになります。

 

テーブルの他の特性を先に削除しない限り、テーブルを削除できないベンダーもあります。たとえば、Microsoft SQL Server では、テーブル自体を削除する前に、テーブルをあらゆるレプリケーションスキーム、および FOREIGN KEY 参照から削除しておく必要があります。

 
ベンダーコマンド
SQL Server変則対応
MySQL変則対応
Oracle変則対応
PostgreSQL変則対応
 
SQL99 の構文および説明
 
DROP TABLE table_name RESTRICT | CASCADE
 

SQL99 の構文では、RESTRICT を指定すると、ビューや制約が削除対象のテーブルを現在参照している場合、DBMS によるこのコマンドの実行を禁止します。CASCADE 句を指定すると、テーブルを参照しているすべてのオブジェクトもテーブルと共に削除されます。

 
Microsoft SQL Server の構文およびバリエーション
 
DROP TABLE [database_name.][owner_name.]table_name [,...n]
GO
 

Microsoft SQL Server では、各テーブル名 (table_name) をコンマで区切ることによって、複数のテーブルを一度に削除することができます。現在のコンテキストの外にあるデータベースのテーブルも、データベース名 (database_name) を指定して削除できます (ユーザーに必要な権限がある場合のみ)。テーブル上の制約やトリガーも、すべてテーブルと共に削除されます。明示的に宣言した規則および初期設定値は、それらの基底テーブルを削除したときにバインディングが失われます。削除したテーブルを参照していたビューおよびストアドプロシージャーでは、実行時にテーブルがないことが分かるとエラーとなります。

 
MySQL の構文およびバリエーション
 
DROP TABLE [IF EXISTS] table_name;
 

MySQL では、このコマンドを実行すると、テーブル (table_name) およびすべての関連ファイルが恒久的に完全に削除されます。IF EXISTS 構文を追加すると、存在しないテーブルを削除しようとした際に返されるエラーを防止できます。

 
Oracle の構文およびバリエーション
 
DROP TABLE [owner_name.]table_name [CASCADE CONSTRAINTS];
 

Oracle でテーブルを削除すると、テーブルが使用していた領域が解放され、データベースに対する保留中のすべての 変更がコミットされます。テーブルを削除すると、それまでテーブルに消費されていたすべての領域が直ちに解放されます。削除したテーブルに関連付けられていたインデックスおよび権限はすべて失われます。テーブルに構築されていたビュー、ストアドプロシージャー、シノニムなどのオブジェクトは無効になり、機能も停止されます。

 

Oracle では、ALTERCREATE、または DROP コマンドを実行すると、保留中のその他のトランザクションがすべてコミットされます。

 

CASCADE CONSTRAINTS 句を指定すると、削除するテーブルのキーを参照しているすべての整合性制約が削除されます。

 
PostgreSQL の構文およびバリエーション
 
DROP TABLE table_name;
 

PostgreSQL では、基本的な DROP TABLE コマンドのみをサポートしています。

 
DROP TRIGGER 

DROP TRIGGER コマンドは現行のデータベース内のテーブルからトリガーを削除します。

 
ベンダーコマンド
SQL Server変則対応
MySQL未対応
Oracle変則対応
PostgreSQL変則対応
 
SQL99 の構文および説明
 
DROP TRIGGER trigger_name
 

DROP TRIGGER は、現行のデータベースからトリガーを削除します。MySQL では、このコマンドをサポートしていません。

 
Microsoft SQL Server の構文およびバリエーション
 
DROP TRIGGER [owner_name.]trigger_name [,...n]
GO
 

Microsoft SQL Server では、各トリガー名 (trigger_name) をコンマで区切ることによって、複数のトリガーを削除できます。

 
Oracle の構文およびバリエーション
 
DROP TRIGGER [owner_name.]trigger_name;
 

Oracle では、このコマンドの実行時に指定したトリガー (trigger_name) を削除し、データベースに対する保留中の変更をコミットします。

 
PostgreSQL の構文およびバリエーション
 
DROP TRIGGER trigger_name ON table_name;
 

PostgreSQL では、トリガー (trigger_name) のあるテーブル (table_name) を指定する必要があります。このコマンドを実行すると、既存のトリガーに対するすべての参照を削除します。

 
DROP VIEW 

この コマンドは、現行のデータベースからビューを恒久的に削除します。

 
ベンダーコマンド
SQL Server対応
MySQL未対応
Oracle対応
PostgreSQL対応
 
SQL99 の構文および説明
 
DROP VIEW view_name RESTRICT | CASCADE
 

SQL99 の構文では、RESTRICT を指定すると、削除するビュー (view_name) が現在テーブルを参照しているか制約を持つ場合、DBMS によるそのビューの削除を禁止します。CASCADE 句を指定すると、ビューを参照しているすべてのオブジェクトもビューと共に削除されます。

 

MySQL では現在、このコマンドをサポートしていません。

 
Microsoft SQL Server の構文およびバリエーション
 
DROP VIEW [owner_name.]view_name [,...n]
GO
 

Microsoft SQL Server では、各ビュー名 (view_name) をコンマで区切ることによって、1 回のコマンドで複数のビューを削除できます。これらのビューは同じデータベース内にある必要があります。ビューに関する情報は、すべてのシステムテーブルから削除されます。

 
Oracle の構文およびバリエーション
 
DROP VIEW [owner_name.]view_name;
 

Oracle の他の DROP コマンド同様、ビュー名 (view_name) と共に、所有者の名前 (owner_name) を指定できます。DROP ANY VIEW システム権限を持つユーザーは、他のユーザーが所有するビューを削除できます。

 
PostgreSQL の構文およびバリエーション
 
DROP VIEW view_name;
 

PostgreSQL では、DROP VIEW コマンドは、現行のデータベースから既存のビュー (view_name) を削除します。ビューを削除できるのは所有者だけです。PostgreSQL の DROP TABLE コマンドは、ビューの削除にも使用できます。

 
FETCH 

FETCH コマンドは、カーソル処理で使用する 4 つのコマンドの中の 1 つです。FETCH は、サーバーサイドカーソルから特定の行を取得します。

 
ベンダーコマンド
SQL Server対応
MySQL未対応
Oracle変則対応
PostgreSQL変則対応
 
SQL99 の構文および説明
 

FETCH コマンドは、カーソル cursor_name (DECLARE CURSOR ステートメントで作成) から、NEXTPRIORFIRSTLASTABSOLUTE、または RELATIVE キーワードに基づいて、レコードを取得します。FETCH ステートメントで取得した値は、オプションで変数に格納できます。次のような FETCH 処理があります。

 
  • NEXT
      カーソルが現在の行の直後のレコードを返すようにし、返される行を現在の行にします。FETCH NEXTFETCH のデフォルトの動作で、カーソルから初めて取得する場合は、最初のレコードを取得します。PostgreSQL では、FORWARD キーワード、または文字列 FETCH RELATIVE NEXT を使用します。
  • PRIOR
      カーソルが現在の行の直前のレコードを返すようにし、返される行を現在の行にします。FETCH PRIOR は、カーソルから初めて取得する場合は、レコードを取得しません。PostgreSQL では、BACKWARD キーワード、または文字列 FETCH RELATIVE PRIOR を使用します。
  • FIRST
      カーソルが最初のレコードを返すようにし、その行を現在の行にします。PostgreSQL ではサポートされていません。
  • LAST
      カーソルが最後のレコードを返すようにし、その行を現在の行にします。PostgreSQL ではサポートされていません。
  • ABSOLUTE { n }
      カーソルが、レコードセットの最初から n 番目 (n が正の場合)、または最後から n 番目 (n が負の場合) のレコードを返すようにし、返されるレコードを新たにカーソルの現在のレコードとします。n が 0 の場合、行は返されません。PostgreSQL ではサポートされていません。
  • RELATIVE { n }
      カーソルが、現在のレコードから n 行後のレコード (n が正の場合)、または現在のレコードの n 行前のレコード (n が負の場合) を返すようにし、返されるレコードを新たにカーソルの現在のレコードにします。n が 0 の場合、現在の行が返されます。PostgreSQL では、n が 0 の場合を除き、上記の説明どおりにサポートされています。
 

INTO キーワードを使用すると、FETCH コマンド内の各列のデータを、ローカル変数に格納できます。FETCH コマンド内の各列は、INTO 句の対応する変数のデータタイプと一致する必要があります。INTO は PostgreSQL ではサポートされていません。

 

PostgreSQL のカーソルは、BEGINCOMMIT、または ROLLBACK を使用して明示的に宣言したトランザクション内でのみ使用できます。PostgreSQL では、数値または ALL キーワードを使用して、指定の数のレコード、またはすべてのレコードを取得できます。

 
Oracle の構文およびバリエーション
 
FETCH cursor_name
{INTO variable_name1 [,...n] ]
| BULK COLLECT INTO [collection_name [,...n] }
 

Oracle のカーソルは、前方にスクロールするカーソルです。取得した値は一致する変数 (variable_name1) に挿入するか、BULK COLLECT 句を使用して、出力を PL/SQL パーサーに渡す前にバルク結合する必要があります。カーソルですべての行を処理するために FETCH を PL/SQL の FOR ループとペアでよく使用します。

 
PostgreSQL の構文およびバリエーション
 
FETCH [ FORWARD | BACKWARD | RELATIVE [ { [ # | ALL | NEXT | PRIOR ] } ]  ]
[ count ]
FROM cursor_name
 

PostgreSQL のカーソルは、BEGINCOMMIT、または ROLLBACK を使用して明示的に宣言したトランザクション内でのみ使用できます。

 

カーソルのスクロール方法には、FORWARDBACKWARD、または RELATIVE を指定できます。RELATIVE 句には、数値または ALL キーワードを指定して、指定数のレコードまたはすべてのレコードを取得できます。

 
 

次の Oracle の例では、employee_new_hires_cursor (DECLARE CURSOR の例を参照) のいくつかの要素を取得し、ローカル変数に格納します。

 
FETCH FROM employee_new_hires_cursor
INTO : emp_id, :fname, :lname, :job_id
 

次の PostgreSQL の例では、employee テーブルから 5 つのレコードを取得します。

 
FETCH FORWARD 5 IN employee_new_hires_cursor;
 
GRANT 

SQL99 では、GRANT ステートメントは、ユーザーおよびロールに、データベースオブジェクトを使用する許可を与えます。また、ほとんどのベンダーでは、データベースオブジェクトの作成、ストアドプロシージャーや関数の実行などの許可をユーザーおよびロールに与えるために GRANT ステートメントを使用します。

 
ベンダーコマンド
SQL Server変則対応
MySQL変則対応
Oracle変則対応
PostgreSQL変則対応
 
SQL99 の構文および説明
 
GRANT { ALL [PRIVILEGES] }
| SELECT
| INSERT [ (column_name [,...n]) ]
| DELETE
| UPDATE [ (column_name [,...n]) ]
| REFERENCES [ (column_name [,...n]) ]
| USAGE }[,...n]
ON { [TABLE] table_name
| DOMAIN domain_name
| COLLATION collation_name
| CHARACTER SET character_set_name
| TRANSLATION translation_name }
TO {grantee_name |  PUBLIC}
[WITH GRANT OPTION]
 

権限のあるユーザーは、GRANT ステートメントを使用して、アクセス権限 (SELECTINSERTUPDATEDELETEREFERENCES、または USAGE) をユーザーに与えることができます。ユーザーは各権限でそれぞれのコマンドを実行できますが、REFERENCES および USAGE はその他の権限を提供します。複数のアクセス 権限を与えるには、各権限をコンマで区切り、すべてのアクセス権限を与えるには ALL を指定します。PRIVILEGES キーワードは省略可能です。

 

USAGE 権限は、テーブルだけでなく、すべてのデータベースオブジェクトに適用されますが、その他の権限はテーブルにのみ適用されます。USAGE 権限のあるユーザーは、変換を使用して照合順序を構築するなど、別の定義に基づいてオブジェクトを作成できます。REFERENCES 権限は、制約内のテーブルを有効にし、外部キーを使用できるようにします。

 

INSERTUPDATE、および REFERENCES 権限は、テーブル内の指定列に割り当てることができます。列を指定しない場合は、すべての列に割り当てられます。

 

ON 句では、ユーザーが権限を受け取る特定のテーブルまたはデータベースオブジェクトを宣言します。

 

TO 句には、指定した権限を受け取るユーザーまたはロールを指定します。また、PUBLIC に権限を付与すると、将来作成されるユーザーも含めてすべてのユーザーに指定の権限が与えられます。WITH GRANT OPTION を使用すると他のユーザーに権限を与えることができます。つまり、この句を指定すると、アクセス権限を受け取るユーザーは、同じアクセス権限を他のユーザーに与えることができます。

 

特定のデータベースの実装によっては、ビューのアクセス権限が、基本テーブルと独立しているものやそうでないものもあります。

 
Microsoft SQL Server の構文およびバリエーション
 
GRANT { ALL [PRIVILEGES] }
| SELECT
| INSERT
| DELETE
| UPDATE
| REFERENCES
| EXECUTE
| CREATE {DATABASE | DEFAULT | FUNCTION | PROCEDURE | RULE | TABLE | VIEW}
| BACKUP {DATABASE | LOG} } [,...n]
ON { {table_name | view_name} [(column [,...n])]
| stored_procedure_name
| extended_stored_procedure_name
| user_defined_function_name
| [(column [,...n] ON {table_name | view_name} }
TO {grantee_name | PUBLIC} [,...n]
[WITH GRANT OPTION]
[AS {group | role}]
 

Microsoft SQL Server では、SELECTINSERTUPDATEDELETE、および REFERENCES アクセス権限をテーブル (table_name) に対して指定できます。列リスト (column) は、SELECT および UPDATE アクセス権限でのみ識別できます。デフォルトでは、すべての列に SELECT および UPDATE アクセス権限が与えられます。

 

ストアドプロシージャー、拡張ストアドプロシージャー、およびユーザー定義関数に与えられる権限は、EXECUTE 権限のみです。FOREIGN KEY 制約を作成するには、ユーザーに REFERENCES 権限がある必要があります。この権限は、SCHEMABINDING を指定してオブジェクトに依存する関数やビューを作成する場合にも必要です。

 

ASは、別のグループやロールのコンテキストであるかのように権限を与えます。グループおよびロールは GRANT コマンドを実行できないので、これは、別のグループやロールのユーザーに権限を与えるのに便利な方法です。現行のデータベースコンテキスト以外のデータベースに権限を与えることはできません。

 
 

最初に、CREATE DATABASE および CREATE TABLE を使用する権限をユーザーの Emily と Sarah に与えます。次に、titles テーブルに関する多数の権限を editors グループに与えます。editors グループは、これらの権限を別のユーザーに与えることができるようになります。

 
GRANT CREATE DATABASE, CREATE TABLE TO emily, sarah
GO

GRANT SELECT, INSERT, UPDATE, DELETE ON titles
TO editors
WITH GRANT OPTION
GO
 
MySQL の構文およびバリエーション
 
GRANT { ALL PRIVILEGES
| SELECT
| INSERT [ (column_name [,...n]) ]
| DELETE
| UPDATE [ (column_name [,...n]) ]
| REFERENCES [ (column_name [,...n]) ]
| USAGE
| ALTER
| CREATE
| DROP
| FILE
| INDEX
| PROCESS
| RELOAD
| SHUTDOWN }[,...n]
ON {table_name | * | *.* | database_name.*}
TO grantee_name [IDENTIFIED BY 'password'] [,...n]
[WITH GRANT OPTION]
 

MySQL では、データベース内のオブジェクト操作に主に関連する追加のアクセス権限が提供されています。他の権限と同様、ALTERCREATEINDEX、または RELOAD などの任意のアクセス権限をユーザーに与えることによって、ユーザーは与えられたコマンドを実行できます。REFERENCES はサポートされていますが、機能はありません。USAGE は、対象ユーザーの権限を実質的に無効化します。

 

テーブル (table_name) に適用できるアクセス権限には、SELECTINSERTUPDATEDELETECREATEDROPGRANTINDEX、および ALTER があります。INSERTUPDATE、および SELECT は、列レベルでも適用できます。

 

MySQL の ON 句の実装では、いくつかの興味深いオプションを設定できます。ON *.* と指定することによって、グローバル権限を設定し、サーバー上のすべてのデータベースに適用できます。ON database_name.* または、現行のデータベース内で ON * を指定することによって、データベース全体の権限を設定できます。ホスト、テーブル、データベース、および列の名前は、60 文字以下に設定する必要があります。

 

MySQL では、特定ホストの特定ユーザー grantee_name の名前が USER@HOST である場合、そのユーザーに権限を与えることができます。grantee_name 内にワイルドカードを指定して、一度に大勢のユーザーにアクセス権限を与えることができます。grantee_name は 16 文字以下である必要があります。ユーザーを指定する場合、IDENTIFIED BY 句を含めて、パスワード保護を実施できます。

 
 

次の例では、2 人のユーザーにパスワード付で権限を与えます。

 
GRANT SELECT ON employee TO Dylan IDENTIFIED BY 'porsche',
  kelly IDENTIFIED BY 'mercedes',
  emily IDENTIFIED BY 'saab';
 
Oracle の構文およびバリエーション
 
GRANT { ALL [PRIVILEGES] }
{| GRANT ANY PRIVILEGE }
{| SELECT | INSERT  | DELETE | UPDATE | REFERENCES }
{| CREATE [ANY] {CLUSTER | CONTEXT | DATABASE| DATABASE LINK | DIMENSION
   | DIRECTORY | INDEXTYPE | INDEX | LIBRARY | OPERATOR | OUTLINE
   | PROCEDURE | PROFILE | ROLE | ROLLBACK SEGMENT | SEQUENCE | SESSION
   | SNAPSHOT | SYNONYM | TABLE | TABLESPACE | TRIGGER | TYPE |
   | USER | [MATERIALIZED] VIEW}
| DROP [ANY] {...as CREATE...}
| ALTER [ANYh] {...as CREATE...}
| AUDIT SYSTEM
| EXECUTE [ANY] {INDEXTYPE | OPERATOR | PROCEDURE | TYPE
| BACKUP [ANY] {TABLE | DATABASE | LOG} } [,...n] }
ON { [schema_name.]
{table_name | view_name} [ (column [,...n]) ]
| stored_procedure_name
| extended_stored_procedure_name
| user_defined_function_name
| DIRECTORY directory_name
| JAVA {SOURCE | RESOURCE} [schema_name.]object_name }
TO {{grantee_name | role_name} [,...n] | PUBLIC}
[WITH ADMIN OPTION];
 

Oracle の GRANT コマンドはあらゆる機能を網羅しています。実際、上記の構文では、ステートメントの各順列がカバーされていません。GRANT コマンドで使用できる一般的な権限には、オブジェクト権限 (特定のテーブルからの SELECTDELETE に対する権限など) とシステム権限 (CREATE CLUSTERDROP ANY TABLE など) の 2 つのクラスがあります。

 

Oracle では、1 つの GRANT コマンド内にオブジェクト権限とシステム権限を組み合わせることはできません。1 つの GRANT コマンドで単一のユーザーやロールに複数のオブジェクト権限やシステム権限を与えることはできますが、1 つの GRANT コマンドでオブジェクト権限とシステム権限の両方を与えることはできません。

 

Oracle でサポートされているほとんどの機能の権限は GRANT コマンドで与えられます。権限は、テーブルやビューなどのデータベースオブジェクトと CREATE ANY TABLE などのシステムコマンドに対してだけでなく、DIRECTORYJAVA SOURCE、および RESOURCE などのスキーマオブジェクトにも与えることができます。

 

ANY オプションは、スキーマ内の任意のユーザーが所有する特定の型のオブジェクトに対して、指定のステートメントを実行する権限を与えます。Oracle のシステム権限の一覧を表 3.2 に示します。

 
権限の種類システム権限説明
クラスターCREATE CLUSTERユーザー自身のスキーマ内にクラスターを作成する権限を与えます。
 CREATE ANY CLUSTER任意のスキーマ内にクラスターを作成する権限を与えます。
 ALTER ANY CLUSTER任意のスキーマのクラスターを変更する権限を与えます。
 DROP ANY CLUSTER任意のスキーマのクラスターを削除する権限を与えます。
コンテキストCREATE ANY CONTEXT任意のコンテキスト名前空間を作成する権限を与えます。
 DROP ANY CONTEXT任意のコンテキスト名前空間を削除する権限を与えます。
データベースALTER DATABASEデータベースを変更する権限を与えます。
 ALTER SYSTEMALTER SYSTEM ステートメントを発行する権限を与えます。
 AUDIT SYSTEMAUDIT sql_statements ステートメントを発行する権限を与えます。
データベースリンクCREATE DATABASE LINKユーザー自身のスキーマ内にプライベートデータベースリンクを作成する権限を与えます。
 CREATE PUBLICDATABASE LINKパブリックデータベースリンクを作成する権限を与えます。
 DROP PUBLICDATABASE LINKパブリックデータベースリンクを削除する権限を与えます。
ディメンションCREATE DIMENSIONユーザー自身のスキーマ内にディメンションを作成する権限を与えます。
 CREATE ANYDIMENSION任意のスキーマ内にディメンションを作成する権限を与えます。
 ALTER ANYDIMENSION任意のスキーマのディメンションを変更する権限を与えます。
 DROP ANYDIMENSION任意のスキーマのディメンションを削除する権限を与えます。
ディレクトリCREATE ANYDIRECTORYディレクトリデータベースオブジェクトを作成する権限を与えます。
 DROP ANYDIRECTORYディレクトリデータベースオブジ ェクトを削除する権限を与えます。
インデックス型CREATE INDEXTYPEユーザー自身のスキーマ内にインデックス型を作成する権限を与えます。
 CREATE ANYINDEXTYPE任意のスキーマ内にインデックス型を作成する権限を与えます。
 ALTER ANYINDEXTYPE任意のスキーマのインデックス型を変更する権限を与えます。
 DROP ANYINDEXTYPE任意のスキーマのインデックス型を削除する権限を与えます。
 EXECUTE ANYINDEXTYPE任意のスキーマのインデックス型を参照する権限を与えます。
インデックスCREATE ANY INDEX任意のスキーマ内にドメインインデックスを作成する権限、または任意のスキーマのテーブルにインデックスを作成する権限を与えます。
 ALTER ANY INDEX任意のスキーマのインデックスを変更する権限を与えます。
 DROP ANY INDEX任意のスキーマのインデックスを削除する権限を与えます。
 QUERY REWRITEマテリアライズドビューまたはインデックスが、ユーザー自身のスキーマ内のテーブルおよびビューを参照する場合、マテリアライズドビューを使用した書き換えを有効にする権限、または関数ベースのインデックスを作成する権限を与えます。
 GLOBAL QUERY REWRITEマテリアライズドビューまたはインデックスが、任意のスキーマ内のテーブルおよびビューを参照する場合、マテリアライズドビューを使用した書き換えを有効にする権限、または関数ベースのインデックスを作成する権限を与えます。
ライブラリCREATE LIBRARYユーザー自身のスキーマ内に外部プロシージャーまたは関数ライブラリを作成する権限を与えます。
 CREATE ANY LIBRARY任意のスキーマ内に外部プロシージャーまたは関数ライブラリを作成する権限を与えます。
 DROP LIBRARYユーザー自身のスキーマの外部プロシージャーまたは関数ライブラリを削除する権限を与えます。
 DROP ANY LIBRARY任意のスキーマの外部プロシージャーまたは関数ライブラリを削除する権限を与えます。
マテリアライズドビュー (スナップショットと同じ)CREATE MATERIALIZED VIEWユーザー自身のスキーマ内にマテリアライズドビューを作成する権限を与えます。
 CREATE ANY MATERIALIZED VIEW任意のスキーマ内にマテリアライズドビューを作成する権限を与えます。
 ALTER ANY MATERIALIZED VIEW任意のスキーマのマテリアライズドビューを変更する権限を与えます。
 DROP ANY MATERIALIZED VIEW任意のスキーマのマテリアライズドビューを削除する権限を与えます。
 GLOBAL QUERY REWRITEマテリアライズドビューまたはインデックスが、任意のスキーマのテーブルまたはビューを参照する場合、マテリアライズドビューを使用した書き換えを有効にする権限、または関数ベースのインデックスを作成する権限を与えます。
 QUERY REWRITEマテリアライズドビューまたはインデックスが、ユーザー自身のスキーマのテーブルおよびビューを参照する場合、マテリアライズドビューを使用した書き換えを有効にする権限、または関数ベースのインデックスを作成する権限を与えます。
演算子CREATE OPERATORユーザー自身のスキーマ内に演算子およびそのバインディングを作成する権限を与えます。
 CREATE ANYOPERATOR任意のスキーマ内に演算子およびそのバインディングを作成する権限を与えます。
 DROP ANY OPERATOR任意のスキーマの演算子を削除する権限を与えます。
 EXECUTE ANYOPERATOR任意のスキーマの演算子を参照する権限を与えます。
アウトラインCREATE ANY OUTLINEアウトラインを使用する任意のスキーマ内で使用できるアウトラインを作成する権限を与えます。
 ALTER ANY OUTLINEアウトラインを変更する権限を与えます。
 DROP ANY OUTLINEアウトラインを削除する権限を与えます。
プロシージャーCREATE PROCEDUREユーザー自身のスキーマ内に、ストアドプロシージャー、関数、およびパッケージを作成する権限を与えます。
 CREATE ANYPROCEDURE任意のスキーマ内に、ストアドプロシージャー、関数、およびパッケージを作成する権限を与えます。
 ALTER ANYPROCEDURE任意のスキーマのストアドプロシージャー、関数、またはパッケージを変更する権限を与えます。
 DROP ANYPROCEDURE任意のスキーマのストアドプロシージャー、関数、またはパッケージを削除する権限を与えます。
 EXECUTE ANYPROCEDUREプロシージャーまたは関数 (スタンドアローンまたはパッケージ) を実行する権限を与えます。
プロファイルCREATE PROFILEプロファイルを作成する権限を与えます。
 ALTER PROFILEプロファイルを変更する権限を与えます。
 DROP PROFILEプロファイルを削除する権限を与えます。
ロールCREATE ROLEロールを作成する権限を与えます。
 ALTER ANY ROLEデータベースの任意のロールを変更する権限を与えます。
 DROP ANY ROLEロールを削除する権限を与えます。
 GRANT ANY ROLEデータベース内の任意のロールを与える権限を与えます。
ロールバックセグメントCREATE ROLLBACK SEGMENTロールバックセグメントを作成する権限を与えます。
 ALTER ROLLBACK SEGMENTロールバックセグメントを変更する権限を与えます。
 DROP ROLLBACK SEGMENTロールバックセグメントを削除する権限を与えます。
シーケンスCREATE SEQUENCEユーザー自身のスキーマ内にシーケンスを作成する権限を与えます。
 CREATE ANY SEQUENCE任意のスキーマ内にシーケンスを作成する権限を与えます。
 ALTER ANY SEQUENCEデータベースの任意のシーケンスを変更する権限を与えます。
 DROP ANY SEQUENCE任意のスキーマのシーケンスを削除する権限を与えます。
 SELECT ANY SEQUENCE任意のスキーマのシーケンスを参照する権限を与えます。
セッションCREATE SESSIONデータベースに接続する権限を与えます。
 ALTER RESOURCE COSTセッションリソースのコストを設定する権限を与えます。
 ALTER SESSIONALTER SESSION ステートメントを発行する権限を与えます。
 RESTRICTED SESSIONSQL*Plus の STARTUP RESTRICT ステートメントを使用してインスタンスが開始された後にログオンする権限を与えます。
スナップショット (マテリアライズドビューと同じ)CREATE SNAPSHOTユーザー自身のスキーマ内にスナップショットを作成する権限を与えます。
 CREATE ANYSNAPSHOT任意のスキーマ内にスナップショットを作成する権限を与えます。
 ALTER ANY SNAPSHOTデータベースの任意のスナップショットを変更する権限を与えます。
 DROP ANY SNAPSHOT任意のスキーマのスナップショットを削除する権限を与えます。
 GLOBAL QUERY REWRITEスナップショットまたはインデックスが、任意のスキーマ内のテーブルおよびビューを参照する場合、スナップショットを使用した書き換えを有効にする権限、または関数ベースのインデックスを作成する権限を与えます。
 QUERY REWRITEスナップショットまたはインデックスが、ユーザー自身のスキーマ内のテーブルおよびビューを参照する場合、スナップショットを使用した書き換えを有効にする権限、または関数ベースのインデックスを作成する権限を与えます。
シノニムCREATE SYNONYMユーザー自身のスキーマ内にシノニムを作成する権限を与えます。
 CREATE ANY SYNONYM任意のスキーマ内にプライベートシノニムを作成する権限を与えます。
 CREATE PUBLIC SYNONYMパブリックシノニムを作成する権限を与えます。
 DROP ANY SYNONYM任意のスキーマのプライベートシノニムを削除する権限を与えます。
 DROP PUBLIC SYNONYMパブリックシノニムを削除する権限を与えます。
テーブルCREATE ANY TABLE任意のスキーマ内にテーブルを作成する権限を与えます。テーブルを含むスキーマの所有者には、テーブル領域にテーブルを格納できるクオータがある必要があります。
 ALTER ANY TABLEスキーマのテーブルまたはビューを変更する権限を与えます。
 BACKUP ANY TABLE他のユーザーのスキーマからオブジェクトを増分エクスポートするエクスポートユーティリティを使用する権限を与えます。
 DELETE ANY TABLE任意のスキーマのテーブル、テーブルのパーティション、またはビューから行を削除する権限を与えます。
 DROP ANY TABLE任意のスキーマのテーブル、またはテーブルのパーティションを削除または切り捨てる権限を与えます。
 INSERT ANY TABLE任意のスキーマのテーブルまたはビューに行を挿入する権限を与えます。
 LOCK ANY TABLE任意のスキーマのテーブルまたはビューをロックする権限を与えます。
 UPDATE ANY TABLE任意のスキーマのテーブルおよびビューの行を更新する権限を与えます。
 SELECT ANY TABLE任意のスキーマのテーブル、ビュー、またはスナップショットへの問い合わせを行う権限を与えます。
テーブル領域CREATE TABLESPACEテーブル領域を作成する権限を与えます。
 ALTER TABLESPACEテーブル領域を変更する権限を与えます。
 DROP TABLESPACEテーブル領域を削除する権限を与えます。
 MANAGE TABLESPACEテーブル領域のオフライン化やオンライン化、およびテーブル領域のバックアップの開始と終了を行う権限を与えます。
 UNLIMITED TABLESPACE任意のテーブル領域を無制限に使用する権限を与えます。この権限は、割り当てられているすべての個別のクオータに優先します。ユーザーのこの権限を取り消すと、ユーザーのスキーマオブジェクトは残りますが、個別のテーブル領域のクオータによって認証されない限り、以降のテーブル領域の割り当ては拒否されます。このシステム権限をロールに与えることはできません。
トリガーCREATE TRIGGERユーザー自身のスキーマ内にデータベーストリガーを作成する権限を与えます。
 CREATE ANY TRIGGER任意のスキーマ内にデータベーストリガーを作成する権限を与えます。
 ALTER ANY TRIGGER任意のスキーマのデータベーストリガーを有効化、無効化、またはコンパイルする権限を与えます。
 DROP ANY TRIGGER任意のスキーマのデータベーストリガーを削除する権限を与えます。
 ADMINISTER DATABASE TRIGGERデータベースにトリガーを作成する権限を与えます。ユーザーは、CREATE TRIGGER または CREATE ANY TRIGGER 権限も持っている必要があります。
CREATE TYPEユーザー自身のスキーマ内にオブジェクト型およびオブジェクト型本体を作成する権限を与えます。
 CREATE ANY TYPE任意のスキーマ内にオブジェクト型およびオブジェクト型本体を作成する権限を与えます。
 ALTER ANY TYPE任意のスキーマのオブジェクト型を変更する権限を与えます。
 DROP ANY TYPE任意のスキーマのオブジェクト型およびオブジェクト型本体を削除する権限を与えます。
 EXECUTE ANY TYPE任意のスキーマのオブジェクト型とコレクション型を使用または参照する権限、および、特定のユーザーに権限を与える場合、任意のスキーマのオブジェクト型のメソッドを呼び出す権限を与えます。ロールに EXECUTE ANY TYPE 権限を与えると、有効化されたロールを保持しているユーザーは、スキーマのオブジェクト型のメソッドを呼び出すことができなくなります。
ユーザーCREATE USERユーザーを作成する権限を与えます。この権限により、作成者は次の操作も行えます。
  1. 任意のテーブル領域へのクオータの割り当て
  2. デフォルトおよび一時テーブル領域の設定
  3. CREATE USER ステートメントの一部としてのプロファイルの割り当て
 ALTER USER任意のユーザーを変更する権限を与えます。この権限により、ユーザーは次の操作も行えます。
  1. 別のユーザーのパスワードまたは認証方法の変更
  2. 任意のテーブル領域へのクオータの割り当て
  3. デフォルトおよび一時テーブル領域の設定
  4. プロファイルおよびデフォルトロールの割り当て
 BECOME USER別のユーザーになる権限を与えます (フルデータベースインポートを実行するユーザーに必須)。
 DROP USERユーザーを削除する権限を与えます。
ビューCREATE VIEWユーザー自身のスキーマ内にビューを作成する権限を与えます。
 CREATE ANY VIEW任意のスキーマ内にビューを作成する権限を与えます。
 DROP ANY VIEW任意のスキーマのビューを削除する権限を与えます。
その他ANALYZE ANY任意のスキーマ内の任意のテーブル、クラスター、またはインデックスを分析する権限を与えます。
 AUDIT ANY任意のスキーマの任意のオブジェクトを、AUDIT schema_objects ステートメントを使用して監査する権限を与えます。
 COMMENT ANY TABLE任意のスキーマの任意のテーブル、ビュー、または列にコメントを付ける権限を与えます。
 FORCE ANYTRANSACTIONローカルデータベースのインダウト分散トランザクションのコミットまたはロールバックを強制し、分散トランザクション障害を誘発する権限を与えます。
 FORCE TRANSACTIONローカルデータベースの権限を与えられたユーザー自身のインダウト分散トランザクションのコミットまたはロールバックを強制する権限が与えられます。
 GRANT ANYPRIVILEGE任意のシステム権限を与える権限を与えます。
 SYSDBAユーザーに次の権限を与えます。
  1. STARTUP および SHUTDOWN 処理の実行
  2. ALTER DATABASE:オープン、マウント、バックアップ、または文字セットの変更
  3. CREATE DATABASE
  4. ARCHIVELOG および RECOVERY
  5. RESTRICTED SESSION 権限の包含
 SYSOPERユーザーに次の権限を与えます。
  1. STARTUP および SHUTDOWN 処理の実行
  2. ALTER DATABASE OPEN/MOUNT/BACKUP ARCHIVELOG および RECOVERY
  3. RESTRICTED SESSION 権限の包含
 
PostgreSQL の構文およびバリエーション
 
GRANT { ALL
| SELECT
| INSERT
| DELETE
| UPDATE
| RULE } [,...n]
ON { object_name }
TO {grantee_name | PUBLIC | GROUP group_name}
 

PostgreSQL では、WITH GRANT OPTION 句や列レベルの許可をサポートしていません。PostgreSQL の GRANT の実装は、WITH GRANT OPTION 句が常に有効とされているかのように機能します。つまり、権限を与えられたすべてのユーザー (grantee_name) は、他のユーザーにその権限を与えることができます。PostgreSQL では、既存のグループ (group_name) が有効な場合、権限を GROUP に割り当てることができます。

 

PostgreSQL では、システムコマンドに対する GRANT をサポートしていませんが、サポートしているベンダーもあります。

 
 

PostgreSQL の GRANT ステートメントのサポートは基礎的なものです。

 
GRANT INSERT ON publishers TO PUBLIC;

GRANT SELECT, UPDATE ON sales TO emily;
 
INSERT 

INSERT ステートメントは、テーブルまたはビューにデータ行を追加します。INSERT ステートメントは、次の方法のいずれかを使用して、テーブルにレコードを入力できます。

 
  1. 指定のテーブル列に CREATE TABLE または ALTER TABLE ステートメントで作成した DEFAULT 値を使用してレコードを挿入する方法。Oracle ではこの方法をサポートしていません。
  2. レコードの各列に挿入する実際の値を宣言する方法。最も一般的に使用されています。
  3. SELECT ステートメントの結果セットをテーブルに挿入する方法。最もすばやくテーブルに多くの値を挿入できます。
 
ベンダーコマンド
SQL Server変則対応
MySQL変則対応
Oracle変則対応
PostgreSQL対応
 
SQL99 の構文および説明
 
INSERT [INTO] [[database_name.]owner.] {table_name | view_name} [(column_
    list)]
{[DEFAULT] VALUES | VALUES (value[,...]) | SELECT_statement }
 

INSERT ステートメントを使用するには、データの挿入対象のテーブルまたはビューを最初に宣言します。INTO キーワードは省略可能です。column_list に、データを受け取るテーブルの各列をコンマで区切り、かっこで囲んで指定します。column_list を省略した場合は、テーブル内に定義されたすべての列を指定したものと想定されます。

 

DEFAULT VALUES メソッドは、VALUES (value[,...]) および SELECT_statement メソッドと相互に排他的です。

 

INSERT . . . VALUES ステートメントは、ステートメントに与えられたリテラル値を使用して、テーブルに 1 行のデータを追加します。INSERT ステートメントを、ネストした SELECT ステートメントと組み合わせて使用すると、テーブルに複数の行をすばやく挿入できます。2 つのテーブル間で INSERT . . . SELECT を使用する場合、両方のテーブルに互換性のあるデータタイプと構造があるようにしてください。ただし、互換性がない個所は SELECT ステートメントで補うことができます。INSERT . . . SELECT は PostgreSQL もサポートしています。

 
Microsoft SQL Server の構文および説明
 
INSERT [INTO] [[database_name.]owner.]
    {table_name | view_name} [(column_list)]
{[DEFAULT] VALUES | list_of_values | SELECT_statement |
 EXEC[UTE] { procedure_name }
    [[@parameter_name=] {value [OUTPUT] | DEFAULT}[,...]}
 

Microsoft SQL Server の INSERT コマンドの実装は、DEFAULT キーワードを使用できる点が異なります。DEFAULT を指定すると、INSERT ステートメントは、新しいレコードの作成時に、指定のテーブルに宣言した初期設定値をすべて使用します。

 

このベンダーの実装の大きな違いは、EXECUTE キーワードです。EXECUTE 句は、動的な Transact-SQL ステートメント、システムストアドプロシージャー、ユーザーストアドプロシージャー、リモートプロシージャーコール (RPC)、または拡張ストアドプロシージャーによって返された結果セットを、SQL Server がローカルテーブルに格納するようにします。

 

たとえば、次の INSERT は、C:\temp ディレクトリを取得して、#ins_exec_container という一時テーブルに格納します。

 
INSERT INTO #ins_exec_container
EXEC master..xp_cmdshell "dir c:\temp"
GO
 
MySQL の構文およびバリエーション
 
INSERT [LOW_PRIORITY | DELAYED] [IGNORE]
[INTO] [[database_name.]owner.] {table_name | view_name} [(column_list)]
{VALUES (value[,...]) | SELECT_statement | SET column=value[,...n]}
 

オプション LOW_PRIORITY を指定すると、MySQL は、テーブルを読むクライアントが他にいなくなるまで、INSERT の実行を遅らせます。これによって、長時間待機する場合があります。DELAYED オプションを指定すると、INSERT がまだ完了していなくても、クライアントは直ちに続行できます。IGNORE キーワードを指定すると、MySQL は、主キーまたは一意キーの値が重複するようなレコードの挿入を行いません。この句を指定せずに、主キーまたは一意キーが重複する挿入を行った場合、INSERT は失敗します。SET column=value 構文は、テーブルの列を宣言し、その列に値 (value) を挿入できます。

 
Oracle の構文および説明
 
INSERT [INTO] [[database_name.]owner.] {table_name | view_name}
   [PARTITION partition_name | SUBPARTITION subpartition_name]
[(column_list)]
{VALUES (value1[,...n]) RETURNING expression1 [,...n] INTO variable1
   [,...n]
 |
SELECT_statement
[WITH {READ ONLY | CHECK OPTION [CONSTRAINT constraint_name]} }
 

Oracle の INSERT ステートメントの実装では、指定のテーブル (table_name)、ビュー (view_name)、またはスナップショットだけでなく、PARTITIONSUBPARTITION キーワードを使用して、テーブル内の指定のパーティション (partition_name) やサブパーティション (subpartition_name) にデータを挿入できます。

 

INSERT ステートメントが SELECT 句と関連している場合は、いくつかの新たな規則が適用されます。SELECT 句を VALUES 句と組み合わせた場合、SELECT 句によって返される最初の 1 行のみがテーブルに挿入されます。SELECTVALUES なしで使用すると、クエリーによって返されるすべての行がテーブルに挿入されます。

 

RETURNING 句は、テーブルではなく、変数に値を挿入するために使用します。RETURNING 句の式と変数は、一対一で対応している必要があります。この句によって返される式は、VALUES 句で記述されているものである必要はありません。たとえば、次の INSERT ステートメントは、sales テーブルにレコードを挿入しますが、バインド変数には完全に別個の値を挿入します。

 
INSERT authors (au_id, au_lname, au_fname, contract )
VALUES ('111-11-1111', 'Rabbit', 'Jessica', 1)
RETURNING hire_date INTO :temp_hr_dt;
 

ここで、RETURNING 句は、hire_dateVALUES 句にリストされていないにもかかわらず、hire_date を返していることが分かります。この例では、hire_date 列に対して初期設定値が確立されているものと想定すると合理的です。LONG データタイプを RETURNING 句で扱うことはできません。RETURNING 句は、INSTEAD OF トリガーのあるビューでは使用できません。

 

さらに、SELECT 句では、WITH オプションを使用できます。WITH READ ONLY は、SELECT 句によって取得された結果セットを INSERT ステートメントが変更できないように指定します。WITH CHECK OPTION 句を指定すると、SELECT 句の結果セットに含まれない行を生成する可能性のあるデータ変更が禁止されます。

 
PostgreSQL の構文および説明
 

PostgreSQL は、SQL99 標準の INSERT ステートメントをサポートしています。前述の SQL99 の構文と使用方法を参照してください。

 
 

次の例では、Microsoft SQL Server データベースの authors テーブルに、作家 Jessica Rabbit の新しい行を挿入します。

 
INSERT INTO authors (au_id, au_lname, au_fname, phone, address, city,
     state, zip, contract )
VALUES ('111-11-1111', 'Rabbit', 'Jessica', DEFAULT, '1717 Main St', NULL,
    'CA', '90675', 1)
 

各列には特定のリテラル値が割り当てられていますが、phone 列には、CREATE TABLE または ALTER TABLE ステートメントで設定された初期設定値が割り当てられ、city 列には NULL が割り当てられます。

 

次は、同じデータを一部使用し、INTO を省略した Microsoft SQL Server の INSERT ステートメントです。

 
INSERT authors (au_id, au_lname, au_fname,  phone, contract )
VALUES ('111-11-1111', 'Rabbit', 'Jessica', DEFAULT, 1)
 

INSERT . . . SELECT を使用して、sales テーブルから new_sales テーブルにデータを読み込みます。

 
INSERT sales
    (stor_id,
    ord_num,
    ord_date,
    qty,
    payterms,
    title_id)
SELECT
    CAST(store_nbr AS CHAR(4)),
    CAST(order_nbr AS VARCHAR(20)),
    order_date,
    quantity,
    SUBSTRING(payment_terms,1,12),
    CAST(title_nbr AS CHAR(1))
FROM new_sales
WHERE order_date >= '01/01/2000'         -- retrieve only the newer records
 
LIKE 演算子 

LIKE 演算子は、SELECTINSERTUPDATE、および DELETE ステートメントで指定した文字列パターンの一致を可能とします。指定するパターンには、特別なワイルドカード文字を含めることもできます。

 
ベンダーコマンド
SQL Server変則対応
MySQL変則対応
Oracle変則対応
PostgreSQL変則対応
 
SQL99 の構文および説明
 
WHERE expression [NOT] LIKE string_pattern
 

LIKE の利便性は、LIKE でサポートされているワイルドカード演算子に依存します。LIKE は、比較において一致する値が見つかった場合、ブール値 TRUE を返します。大文字小文字の区別に関する DBMS のデフォルトは、LIKE の動作にとって非常に重要です。たとえば、Microsoft SQL Server はデフォルトでは大文字小文字を区別しません。ただし、区別するように設定できます。クエリーの例を次に示します。

 
SELECT *
FROM authors
WHERE lname LIKE 'LARS%'
 

このクエリーでは、大文字の LARS% で検索した場合でも、姓 (lname) が larson または lars の作家を取り出します。Oracle では、% および _ のパターン文字に対して大文字小文字を区別し、LIKE 以外の演算子を使用した他の正規表現パターン一致があります。ワイルドカード演算子を表 3.3 に示します。

 
ワイルドカード演算子説明
%city 列に "ville" が含まれる名前のすべてのレコードを検索します。すべてのベンダーがサポートしています。
SELECT * FROM authors
WHERE city LIKE '%ville%'
あらゆる文字列に一致します。DOS の * の操作に似ています。
[ ]姓 (au_name) が、Carson、Carsen、Karson、または Karsen のすべての作家を検索します。Oracle ではサポートされていませんが、Microsoft SQL Server ではサポートされています。
SELECT * FROM authors
WHERE au_lname LIKE '[CK]ars[eo]n'
[abc] や [k-n] のように指定した集合や範囲に含まれる文字に一致します。
[^ ]姓 (au_name) が arson または arsen (ただし Larsen や Larson ではない) で終わるすべての作家を検索します。Microsoft SQL Server でサポートされています。
SELECT * FROM authors
WHERE au_lname LIKE '[A-Z^L]ars[eo]n'
指定した集合や範囲に含まれないすべての文字に一致します。
_ (アンダースコア)名前 (au_fname) が Sheryl や Cheryl などではない、すべての作家を検索します。すべてのベンダーがサポートしています。
SELECT * FROM authors
WHERE au_fname NOT LIKE '_heryl'
任意の 1 文字に一致します。
 

LIKE を使用して文字列を比較する場合は、前後の空白スペースを含むパターン文字列内のすべての文字が比較対象となります。

 
OPEN  

OPEN コマンドは、DECLARE CURSOR ステートメントで作成したサーバーカーソルを開きます。MySQL では、ANSI 方式のサーバーサイドカーソルはサポートしていません。

 
ベンダーコマンド
SQL Server対応
MySQL未対応
Oracle対応
PostgreSQL対応
 
SQL99 の構文および説明
 
OPEN { cursor_name }
 

cursor_name には、DECLARE CURSOR コマンドで作成したカーソルの名前を指定します。

 

標準的なサーバーカーソルに加えて、Microsoft SQL Server では、複数のユーザーが参照できるグローバルカーソルを OPEN GLOBAL cursor_name のフォーマットで宣言できます。また、Oracle では、OPEN cursor_name parameter1 [,...n] のフォーマットを使用して、カーソルを開く際にパラメータをカーソルに直接渡すことができます。

 
 

次の Microsoft SQL Server の例では、カーソルを開き、すべての行を取得します。Oracle および PostgreSQL では、最後の DEALLOCATAE 句を使用せずに同じ機能を実行できます。

 
DECLARE employee_cursor CURSOR FOR
  SELECT lname, fname
  FROM pubs.dbo.authors
  WHERE lname LIKE 'K%'

OPEN employee_cursor

FETCH NEXT FROM employee_cursor

WHILE @@FETCH_STATUS = 0
BEGIN
  FETCH NEXT FROM Employee_Cursor
END

CLOSE employee_cursor

DEALLOCATE employee_cursor
-- DEALLOCATE is specific to Microsoft SQL Server and non-ANSI
-- standard.
 
演算子 

演算子は、式に対して行う操作を指定する記号です。演算子は、DELETEINSERTSELECT、または UPDATE ステートメントだけでなく、ストアドプロシージャー、関数、トリガー、およびビューなどの データベースオブジェクトの作成にもよく使用されます。

 
ベンダーコマンド
SQL Server変則対応
MySQL変則対応
Oracle変則対応
PostgreSQL変則対応
 

演算子は、通常、次の論理カテゴリに分かれます。

 
  • 算術演算子
      すべてのデータベースでサポートされています。
  • 代入演算子
      すべてのデータベースでサポートされています。
  • ビットごとの演算子
      Microsoft SQL Server でサポートされています。
  • 比較演算子
      すべてのデータベースでサポートされています。
  • 論理演算子
      Oracle、Microsoft SQL Server、および PostgreSQL でサポートされています。
  • 単項演算子
      Oracle でサポートされています。
 
算術演算子
 

算術演算子は、数値データタイプに分類される任意のデータタイプを持つ 2 つの式の算術演算を行います。算術演算子の一覧を表 3.4 に示します。

 
算術演算子意味
+ 加算
- 減算
* 乗算
/ 除算
% 剰余 (SQL Server のみ) : 除算による余りを整数で返します。
 

Oracle および SQL Server では、+ 演算子と - 演算子を日付値の算術演算にも使用できます。

 
代入演算子
 

Oracle を除いて、 代入演算子 (=) は、値を変数または列見出しのエイリアスに代入します。Microsoft SQL Server では、キーワード AS を、テーブル見出しまたは列見出しのエイリアスに代入を行う演算子に割り当てています。

 
ビットごとの演算子
 

Microsoft SQL Server では、2 つの整数式の間でビット演算を簡単に行うためにビットごとの演算子を提供しています (表 3.5 参照)。ビットごとの演算子にアクセスできる有効なデータタイプは、binarybitintsmallinttinyint、および varbinary です。

 
ビットごとの演算子意味
& ビットごとの論理積 (2 オペランド)
| ビットごとの論理和 (2 オペランド)
^ ビットごとの排他的論理和 (2 オペランド)
 
比較演算子
 

比較演算子は、2 つの式が等しいかどうかをテストします。比較演算子の結果は、TRUEFALSE または UNKNOWN のいずれかのブール値です。また、ANSI 規格では、比較演算対象式のいずれかが NULL の場合は NULL が返されます。たとえば、式 23 + NULLNULL を返します。式 Feb 23, 2002 + NULL も同様です。比較演算子の一覧を表 3.6 に示します。

 
比較演算子意味
= 等しい
>より大きい
<より小さい
>= より大きいか等しい (以上)
<=より小さいか等しい (以下)
<>等しくない
!= 等しくない (ANSI 規格外)
!<小さくない (ANSI 規格外)
!>大きくない (ANSI 規格外)
 

ブール値比較演算子は、検索条件を満たす行を見つけるために、 WHERE 句でよく使用されます。次の Microsoft SQL Server の例では、比較演算子の "以上" が使用されています。

 
SELECT *
   FROM Products
   WHERE ProductID >= @MyProduct
 
論理演算子
 

論理演算子は、一般に、特定の条件の真偽をテストするために WHERE 句で使用されます。論理演算子は、TRUE または FALSE のいずれかのブール値を返します。論理演算子については、SELECT の項でも説明します。すべての RDBMS ですべての演算子がサポートされているわけではありません。論理演算子の一覧を表 3.7 に示します。

 
論理演算子意味
ALL比較セットがすべて TRUE の場合、TRUE を返します。
AND 両方の論理式が TRUE の場合、TRUE を返します。
ANY比較セットのいずれかが TRUE の場合、TRUE を返します。
BETWEENオペランドが範囲内の場合、TRUE を返します。
EXISTSサブクエリーに行が含まれる場合、TRUE を返します。
INオペランドが式リストのいずれかに等しい場合、TRUE を返します。
LIKEオペランドがパターンと一致する場合、TRUE を返します。
NOT他の論理演算子の値を反転します。
OR論理式のいずれかが TRUE の場合、TRUE を返します。
SOME比較セットのいくつかが TRUE の場合、TRUE を返します。
 
単項演算子
 

単項演算子は、数値データタイプに分類される任意のデータタイプの 1 つの式に対してのみ演算を行います。単項演算子は、整数データタイプに対して使用できますが、正負は、任意の数値データタイプで使用できます (表 3.8 参照)。

 
単項演算子意味
+数値は正です。
- 数値は負です。
~ビットごとの NOT で、値の補数を返します。Oracle ではサポートされていません。
 
演算子の優先順位
 

演算子の式が複雑になる場合があります。式に複数の演算子が含まれる場合、演算子の優先順位によって、演算が実行される順序が決定されます。実行順序は結果の値に大きく影響します。

 

演算子には次の優先レベルがあります。レベルの高い演算子は、低い演算子より前に評価されます。

 
  1. ( ) (かっこ)
  2. +, -, ~ (単項演算子)
  3. *, /, % (乗除算演算子)
  4. +, - (加減演算子)
  5. =, >, <, >=, <=, <>, !=, !>, !< (比較演算子)
  6. ^ (ビットごとの排他的論理和), & (ビットごとの論理積), | (ビットごとの論理和)
  7. NOT
  8. AND
  9. ALL, ANY, BETWEEN, IN, LIKE, OR, SOME
  10. = (変数への代入)
 

同じ優先順位の演算子は、左から右の順に評価されます。ただし、かっこは式の中の演算子のデフォルト順位に優先して使用されます。かっこ内の式が最初に評価され、次にかっこ外の演算が評価されます。

 

たとえば、次の Oracle のクエリー内の式は、それぞれ全く異なる結果を返します。

 
SELECT 2 * 4 + 5 FROM dual
-- Evaluates to 8 + 5 which yields an expression result of 13.

SELECT 2 * (4 + 5) FROM dual
-- Evaluates to 2 * 9 which yields an expression result of 18.
 

ネストしたかっこを使用した式では、最も深くネストした式が最初に評価されます。

 

次の例では、5 - 3 という最も深くネストしたかっこの組が式に含まれています。この式の値は 2 となります。次に、加算演算子 (+) がこの結果を 4 に追加して、値が 6 となります。最後に、62 が掛けられ、式の結果は 12 となります。

 
SELECT 2 * (4 + (5 - 3) ) FROM dual
-- Evaluates to 2 * (4 + 2) which further evaluates to 2 * 6, and
-- yields an expression result of 12.
 
RETURN  

RETURN ステートメントは、ホストが起動した関数ではなく、SQL で起動した関数内の処理を終了し、関数の結果値を返します。

 
ベンダーコマンド
SQL Server対応
MySQL対応
Oracle対応
PostgreSQL対応
 
SQL99 の構文および説明
 
RETURNS return_parameter_value | NULL
 

RETURN 関数は関数内で使用され、その関数の処理を終了します。NULL 句を指定すると、関数は実際の値を返さずに終了します。NULL 句を指定しない場合は、指定したパラメータ値 (return_parameter_value) が、変数またはリテラル式として返されます。

 

RETURN ステートメントは、SQL 内では独立したコマンドとして分類されますが、このステートメントは、CREATE FUNCTION ステートメントと深く関係しています。各ベンダーの RETURN の実装の詳細については、CREATE FUNCTION ステートメントの項を参照してください。

 
 

次の例では、関数 (project_revenue) を作成します。この関数は、proj_rev 変数に格納されている値を呼び出しセッションに返します。

 
CREATE FUNCTION project_revenue (project IN varchar2)
RETURN NUMBER
AS
   proj_rev NUMBER(10,2);
BEGIN
   SELECT SUM(DECODE(action,'COMPLETED',amount,0) -
          SUM(DECODE(action,'STARTED',amount,0)   +
          SUM(DECODE(action,'PAYMENT',amount,0)
   INTO proj_rev
   FROM construction_actions
   WHERE project_name = project;
   RETURN (proj_rev);
END;
 

次の例では、計算結果の値を呼び出しセッションに返す関数 (metric_volume) を作成します。

 
CREATE FUNCTION metric_volume -- Input dimensions in centimeters.
   (@length decimal(4,1),
   @width decimal(4,1),
   @height decimal(4,1) )
RETURNS decimal(12,3) -- Cubic Centimeters.
AS
BEGIN
   RETURN ( @length * @width * @height )
END
GO
 
REVOKE 

REVOKE ステートメントは、特定のデータベースオブジェクトまたはシステムコマンドに対するユーザー、グループ、またはロールの権限を取り消します。

 
ベンダーコマンド
SQL Server変則対応
MySQL変則対応
Oracle変則対応
PostgreSQL変則対応
 
SQL99 の構文および説明
 
REVOKE [GRANT OPTION FOR]
{ ALL PRIVILEGES }
| SELECT
| INSERT
| DELETE
| UPDATE
| REFERENCES
| USAGE }[,...n]
ON { [TABLE] table_name
| DOMAIN domain_name
| COLLATION collation_name
| CHARACTER SET character_set_name
| TRANSLATION translation_name }
FROM {grantee_name | PUBLIC} [,...n]
{CASCADE | RESTRICT}
 

特定のデータベースオブジェクトに対する特定の権限を単一のユーザーから取り消すには、REVOKE privilege_name ON object_name FROM grantee_name というコマンドを使用します。特定のオブジェクトに対する特定の権限をすべてのユーザーから取り消すには、PUBLIC 句を使用します。また、REVOKE GRANT OPTION FOR 句を使用すると、WITH GRANT OPTION による権限を取り消すことができます。

 

RESTRICT オプションは、指定した権限のみを取り消します。CASCADE オプションは、指定した権限とその権限に依存するすべての権限を取り消します。依存する権限を取り消すオプションの動作は、データベースによって異なる場合があります。このオプションの実際の動作については、ベンダーのマニュアルを参照してください。

 
Microsoft SQL Server の構文およびバリエーション
 
REVOKE [GRANT OPTION FOR]
{ALL [ PRIVILEGES ]
| SELECT
| INSERT
| DELETE
| UPDATE
| REFERENCES
| EXECUTE
| CREATE {DATABASE | DEFAULT | FUNCTION | PROCEDURE | RULE | TABLE | VIEW}
| BACKUP {DATABASE | LOG} } [,...n]
ON { {table_name | view_name} [(column [,...n])]
| stored_procedure_name
| extended_stored_procedure_name
| user_defined_function_name
| [(column [,...n] ON {table_name | view_name} }
{TO | FROM} {grantee_name} [,...n]
[CASCADE]
[AS {group_name | role_name} ]
 

このコマンドは基本的に SQL99 に準拠していますが、GRANT コマンドに実装されている拡張機能については相違点があります。

 

権限が WITH GRANT OPTION でユーザーに付与されている場合、その権限を取り消すには、GRANT OPTION FORCASCADE の両方を使用する必要があります。

 

REVOKE は、現在のデータベースでのみ使用できます。また REVOKE は、DENY 設定を無効にするためにも使用されます。

 

Microsoft SQL Server では、DENY ステートメントが独自にサポートされています。DENY は、構文上は REVOKE と似ていますが、概念が異なります。REVOKE がユーザーの権限を取り消すものであるのに対し、DENY はユーザーの権限を明示的に禁止します。DENY ステートメントは、ユーザーまたはロールによる権限へのアクセスを禁止する場合に使用します。

 
 
REVOKE CREATE DATABASE, CREATE TABLE FROM emily, sarah
GO

REVOKE GRANT OPTION FOR
SELECT, INSERT, UPDATE, DELETE ON titles
TO editors
GO
 
MySQL の構文およびバリエーション
 
REVOKE { ALL PRIVILEGES
| SELECT
| INSERT [ (column_name [,...n]) ]
| UPDATE [ (column_name [,...n]) ]
| REFERENCES [ (column_name [,...n]) ]
| DELETE
| USAGE
| ALTER
| CREATE
| DROP
| FILE
| INDEX
| PROCESS
| RELOAD
| SHUTDOWN } [,...n]
ON {table_name | * | *.* | database_name.*}
FROM user_name [,...n]
 

REVOKE ステートメントは、ユーザーに付与されている任意の権限を取り消します。GRANT ステートメントの項で説明したように、権限はグローバルに取り消すことができます。また、MySQL による REVOKE の実装では、削除済みのオブジェクトに対する権限は明示的には取り消されません。したがって、テーブルが既に削除済みであっても、そのテーブルに対する権限を明示的に REVOKE で取り消す必要があります。これ以外の点では、MySQL は REVOKE コマンドの SQL99 標準に準拠しています。

 
 

1 つ目のコマンドは、sales テーブルに対する Emily と Dylan のすべての権限を取り消します。2 つ目のコマンドは、現在のデータベースにおける Kelly のすべての権限を取り消します。

 
REVOKE ALL PRIVILEGES ON sales FROM emily, dylan;

REVOKE * employee FROM kelly;
 
Oracle の構文およびバリエーション
 
REVOKE {ALL [PRIVILEGES] | [object_privilege] }
ON { [schema_name.][object] | [DIRECTORY directory_object_name] }
FROM {grantee_name | role | PUBLIC} [,...n]
[CASCADE [CONSTRAINTS] ] [FORCE];

REVOKE {system_privilege | role}
FROM {grantee_name | role | PUBLIC} [,...n];
 

Oracle の REVOKE コマンドは、オブジェクト権限 (object_privilege) やシステム権限 (system_privilege) を取り消せるだけでなく、ロール (role) を、指定したユーザー (grantee_name) または別のロールから取り消せます。REVOKE コマンドでサポートされている特定のオブジェクト権限およびシステム権限の詳細については、GRANT ステートメントの項を参照してください。

 

REVOKE コマンドの 2 つの形態である REVOKE object_privilegeREVOKE system_privilege は、相互に排他的です。両方の操作を 1 つのステートメントで実行することはできません。

 

あるユーザーの権限を取り消すと、そのユーザーによって付与されたすべてのユーザーの権限も取り消されます。

 

GRANT ANY ROLE システム権限を付与されたユーザーは、任意のロールを取り消すこともできます。REVOKE コマンドで取り消すことができるのは GRANT コマンドで明示的に付与された権限のみであり、ロールまたはオペレーティングシステムを介して付与された権限を取り消すことはできません。

 

ON DIRECTORY 句では、権限を取り消すディレクトリオブジェクトを指定します。CASCADE CONSTRAINTS 句は、REFERENCES 権限が取り消された場合に、ユーザーによって作成されたすべての参照整合性制約を削除します。FORCE 句は、依存関係を持つユーザー定義テーブルおよび型オブジェクトに対する EXECUTE 権限を取り消します。この結果、これらのオブジェクトは再コンパイルされるまで無効または使用不可となります。

 
 

ロールからユーザーを取り消します。

 
REVOKE read-only FROM sarah;
 

システムコマンド権限を取り消します。

 
REVOKE CREATE ANY SEQUENCE, CREATE ANY DIRECTORY FROM read_only;
 

REFERENCES 権限を取り消します。

 
REVOKE REFERENCES
ON pubs_new_york.emp
FROM dylan
CASCADE CONSTRAINTS;
 
PostgreSQL の構文およびバリエーション
 
REVOKE { ALL
| SELECT
| INSERT
| DELETE
| UPDATE
| RULE
| REFERENCES
| USAGE} [,...n]
ON {object_name}
TO {grantee_name | PUBLIC | GROUP group_name}
{CASCADE | RESTRICT}
 

PostgreSQL では、テーブル、ビュー、およびシーケンスに対するアクセス権を取り消せます。それ以外の点は、SQL99 のコマンドと同じです。SQL99 の REVOKE の構文の説明と、GRANT の説明を参照してください。

 
ROLLBACK 

ROLLBACK ステートメントは、開始地点または SAVEPOINT で宣言された地点までトランザクションを取り消します。このコマンドは、COMMIT と同様に、開いているカーソルを閉じ、ロックを解放します。

 
ベンダーコマンド
SQL Server変則対応
MySQL未対応
Oracle対応
PostgreSQL対応
 
SQL99 の構文および説明
 
ROLLBACK [WORK]
[TO SAVEPOINT savepoint_name]
 

ROLLBACK ステートメントは、単一のデータ操作処理またはデータ操作処理のグループを終了し、最後に発行された BEGIN または SAVEPOINT ステートメントの地点までトランザクションを取り消します。

 

SQL99 では、オプションのキーワード AND CHAIN が新たに定義されています。このコマンドに対応しているベンダーはまだありません。この新しい構文を次に示します。

 
ROLLBACK [WORK] [AND [NO] CHAIN]
 

AND CHAIN オプションは、現在のトランザクションを停止し、トランザクション隔離レベルなどの共通のトランザクション環境を次のトランザクションと共有するよう指示します。AND NO CHAIN オプションを指定すると、単に 1 つのトランザクションが終了されます。ROLLBACK コマンドは、ROLLBACK WORK AND NO CHAIN コマンドの機能と同じです。

 
Microsoft SQL Server の構文およびバリエーション
 
ROLLBACK [TRAN[SACTION] [transaction_name |
 @tran_name_variable |
savepoint_name | @savepoint_variable] ]
 

ROLLBACK は、現在のオープントランザクション (transaction_name) に対するデータ変更、または指定した既存のセーブポイント (savepoint_name) までのデータ変更をすべて取り消します。ROLLBACK を単独で発行した場合は、現在のオープントランザクションがロールバックされます。通常、ROLLBACK はロックを解放しますが、セーブポイントへのロールバックの場合は解放しません。ネストしたトリガーに関しては、ROLLBACKCOMMIT と同じように動作し、@@TRANCOUNT システム変数の値を 1 ずつ減少します。

 

トリガーの中で発行された場合、ROLLBACK TRANSACTION は、そのトリガーで実行されたものも含め、ROLLBACK ステートメントまでのすべてのデータ変更を取り消します。ネストしたトリガーは、トリガーの中で ROLLBACK 以降にある場合は実行されません。ただし、そのトリガーの中で ROLLBACK 以降にあるステートメントはロールバックの影響を受けません。

 
Oracle の構文およびバリエーション
 
ROLLBACK [WORK] [TO savepoint_name] [FORCE text];
 

ROLLBACK は、現在のオープントランザクション (transaction_name) に対するデータ変更、または指定した既存のセーブポイント (savepoint_name) までのデータ変更をすべて取り消します。Oracle の実装は、ほぼ SQL 標準に準拠していますが、FORCE オプションを指定できる点が異なります。ROLLBACK FORCE は、インダウト分散トランザクションまでロールバックします。インダウト分散トランザクションに関する情報は、Oracle のシステムビュー DBA_2PC_PENDING に格納されます。

 
PostgreSQL の構文およびバリエーション
 
{ROLLBACK | ABORT} [WORK | TRANSACTION];
 

ROLLBACK は、現在のオープントランザクション (transaction_name) に対するデータ変更、または指定した既存のセーブポイント (savepoint_name) までのデータ変更をすべて取り消します。PostgreSQL は、SQL99 の WORK オプションと TRANSACTION オプションの両方をサポートしています。セーブポイントへのロールバックはサポートしてません。ABORT オプションは、ROLLBACK の完全なシノニムとして使用できます。

 
 

COMMIT および ROLLBACK を使用した Microsoft SQL Server の Transact-SQL バッチを次に示します。このバッチは、sales テーブルにレコードを挿入します。レコードの挿入に失敗した場合、トランザクションはロールバックされます。ステートメントの実行に成功した場合、トランザクションはコミットされます。

 
BEGIN TRAN -- initializes a transaction

-- the transaction itself
INSERT INTO sales
VALUES('7896','JR3435','Oct 28 1997',25,'Net 60','BU7832')

-- some error-handling in the event of a failure
IF @@ERROR <> 0
BEGIN
    -- raises an error in the event log and skips to the end
    RAISERROR 50000 'Insert of sales record failed'
    ROLLBACK WORK
    GOTO end_of_batch
END

-- the transaction is committed if no errors are detected
COMMIT TRAN

-- the GOTO label that enables the batch to skip to the end without
-- committing
end_of_batch:
GO
 
SAVEPOINT  

このコマンドは、現在のトランザクション内にセーブポイントを作成します。SAVEPOINT コマンドを使用すると、トランザクションを論理的なブレークポイントで分割できます。セーブポイントは、1 つのトランザクション内に複数指定することができます。SAVEPOINT コマンドの最大の利点は、ROLLBACK コマンドを使用して、トランザクションを固有のセーブポイントマーカーまで部分的にロールバックできることです。

 
ベンダーコマンド
SQL Server変則対応
MySQL未対応
Oracle対応
PostgreSQL未対応
 
SQL99 の構文および説明
 
SAVEPOINT savepoint_name
 

一部のベンダーでは、1 つのトランザクション内に重複した名前のセーブポイントを作成できますが、これは推奨されません。":X" のフォーマットで代替セーブポイント識別子を指定すると、名前の代わりに整数値でセーブポイントを追跡できます。ただし、この方法はすべてのベンダーでサポートされているわけではないので、これが最善な方法というわけではありません。

 

SQL99 では、既存のセーブポイントを削除する RELEASE SAVEPOINT savepoint_name ステートメントがサポートされていますが、これは本マニュアルで扱ういずれのベンダーでもサポートされていません。

 
Microsoft SQL Server の構文およびバリエーション
 
SAVE TRAN[SACTION] {savepoint_name | @savepoint_variable}
 

Microsoft SQL Server では、SAVEPOINT コマンドはサポートされていません。代わりに、SAVE コマンドを使用します。セーブポイントのリテラル名を宣言する代わりに、セーブポイントの名前を格納した変数を参照できます。

 

ROLLBACK TRAN savepoint_name コマンドが実行されると、SQL Server はトランザクションを適切なセーブポイントまでロールバックします。次に、ROLLBACK ステートメント以降にある有効な Transact-SQL コマンドの位置から処理を続行します。そして、COMMIT ステートメントまたは最後の ROLLBACK ステートメントでトランザクションを終了させます。

 
Oracle の構文およびバリエーション
 
SAVEPOINT savepoint_name
 

Oracle は SQL99 の実装を完全にサポートしています。

 
 

次の例は、いくつかのデータを変更し、セーブポイントにロールバックした後、トランザクションを完全にロールバックします。

 
INSERT INTO sales VALUES('7896','JR3435','Oct 28 1997',25,'Net
60','BU7832');

SAVEPOINT after_insert;

UPDATE sales SET terms = 'Net 90'
WHERE sales_id = '7896';

SAVEPOINT after_update;

DELETE sales;

ROLLBACK TO after_insert;
ROLLBACK;
 
SELECT 

SELECT ステートメントは、データベースに格納されているテーブルから、行、列、および演算で得られる値を取得します。

 
ベンダーコマンド
SQL Server変則対応 (ANSI 結合に対応)
MySQL変則対応 (ANSI 結合に一部対応)
Oracle変則対応 (ANSI 結合には未対応)
PostgreSQL変則対応 (ANSI 結合に一部対応)
 
SQL99 の構文および説明
 

SELECT ステートメントの構文は高機能かつ複雑ですが、次の主要な句に分けることができます。

 
SELECT [ALL | DISTINCT] select_list
FROM table_name1 [,..., table_nameN]
[JOIN join_condition]
[WHERE search_condition]
[GROUP BY group_by_expression]
[HAVING search_condition]
[ORDER BY order_expression [ASC | DESC] ]
 

SELECT ステートメントの句には、それぞれ固有の用途があります。そのため、FROM 句、WHERE 句、または GROUP BY 句について個別に説明することも可能です。しかし、すべてのクエリーですべての句が必要なわけではありません。クエリーに最低限必要なのは、SELECT 項目リストと FROM 句です。Microsoft SQL Server と PostgreSQL では、FROM 句を必要としない特定のタイプのクエリーがサポートされています。詳細については、次の例を参照してください。

 
SELECT 項目リスト
 

基本的に、SELECT 項目リストには、データベースから取得する情報の項目をすべて指定します。SELECT 項目リストにはタイプの異なる要素を指定することもでき、リテラル文字列、集計関数、および数値計算を取得できます。Microsoft SQL Server では、SELECT 項目リストにサブクエリーを含めることもできます。

 

ALL はデフォルトで、初期設定値を含め、すべてのレコードが返されることを意味します。DISTINCT キーワードは、重複するレコードを返さないようにする場合に指定します。この場合、結果セットには同じレコードは 1 つしか含まれないことになります。

 

SELECT 項目リストに指定できる要素については、他にも次のような規則があります。

 
  1. 通常、取得する列は、コンマで区切ってすべて指定する必要があります。
  2. アスタリスク (*) は、FROM 句に指定したすべてのテーブルから、CREATE TABLE ステートメントで指定したすべての列を取得するための省略表記として使用できます。
  3. 列エイリアスを指定すると、結果セットでデフォルトの列見出しの代わりにこのエイリアスが使用されます。列エイリアスは、column AS "alias" または column alias のフォーマットで指定します。これは、列見出しが簡潔すぎたり長すぎたりして意味が分かりにくい場合に特に便利です。次に例を示します。
  4. ローカル変数およびグローバル変数 (サポートされている場合) を SELECT 項目リストに指定できます。
  5. 2 連ダッシュ ( ) またはスラッシュとアスタリスク (/* ... */) を使用して、任意の SQL または Transact-SQL ステートメント中にコメントを記述できます。2 連ダッシュを指定した場合、それ以降、行末までにあるテキストは無視されます。スラッシュを指定した場合は、スラッシュとアスタリスク (/*) およびアスタリスクとスラッシュ (*/) に囲まれているテキストが無視されます。
  6. クエリーで複数のテーブルを指定する場合は、列名の前にテーブル名を付ける必要があります。厳密に言えば、テーブル名は両方のテーブルのすべての列名に付ける必要があります。一般的にも、このようにしておくことが推奨されます。たとえば、次のように jobs テーブルと employee テーブルの両方に job_id という列が存在する場合があります。
  7. 現在のユーザーのコンテキスト外からデータを取り出す場合は、列名の前にスキーマ名または所有者名を指定する必要があります。テーブルが別のユーザー名で所有されている場合は、そのユーザー名を列参照に含めなければなりません。たとえば、次のクエリーは PUBS データベースで実行していますが、SALES データベースからもデータを取り出しています。
  8. リテラル式を SELECT リスト項目として使用できます。
  9. 算術演算を SELECT リスト項目に指定できます。この場合、Microsoft SQL Server では FROM 句は不要です。Oracle では、このような計算は DUAL というシステムテーブルに対して実行する必要があります。このテーブルを使用することにより、テーブルの存在しない値を SELECT コマンドで取得することができます。次に例を示します。
 
FROM 句
 

一般に、FROM 句には次の 2 つの目的があります。クエリーによるデータの取得元となるテーブルおよびビューを指定する (各テーブル名はコンマで区切る) ことと、長いテーブル名にエイリアスを割り当て、長いクエリーの作成を容易にすることです。FROM 句でエイリアスを割り当てるには、テーブル名、スペース 1 つ、エイリアスの順に記述するか、またはテーブル名、AS、エイリアスの順に記述します。この 2 つの割り当て方法の例を以下に示します。複数のテーブルからデータを取得するクエリーでは、FROM 句および WHERE 句は次のように記述される場合があります。

 
SELECT   e.emp_id,
         e.fname,
         e.lname,
         j.job_desc
FROM     employee e,
         jobs AS  j
WHERE    e.job_id = j.job_id
ORDER BY e.fname,
         e.lname
 

クエリーの中でいったんエイリアスを割り当てたら、そのクエリー内でのテーブル参照には、必ずそのエイリアスを使用する必要があります。1 つのクエリーの中で、完全なテーブル名への参照とエイリアスへの参照を混在させることはできません

 

上記のクエリーは、employee テーブルに格納されている従業員の個人コード (emp_id)、姓、名と JOBS テーブルにある職種の説明 (job_desc) を、従業員の職種コードである job_id を使用して結合しています。

 
JOIN 句
 

非 ANSI 規格の実装では、結合操作は WHERE 句で行います (WHERE 句の説明を参照)。ANSI SQL-92 標準では、結合はクエリーの JOIN 句で行います。これらの結合方法はそれぞれ、シータ結合、および ANSI 結合と呼ばれています。

 

2 つ以上のテーブルのデータを結合して取得するには、まずそれらのテーブルが意味のある関係を共有している必要があります。結合対象のテーブルを意味のある形でリンクするには、それらのテーブルに、共通の値セットを持つ列がなければなりません。このような列のことを、結合キーまたは共通キーと呼びます。必ずというわけではありませんが、ほとんどの場合、結合キーは一方のテーブルの主キーであり、他方のテーブルの外部キーです。これらの列のデータが一致していれば、結合を実行できます。

 

PUBS データベースの employee テーブルと jobs テーブルには、どちらも job_id 列があります。したがって、job_idemployee テーブルと jobs テーブルの共通キーとなります。

 

ANSI 結合を使用するクエリーでは、1 つ目のテーブルと JOIN キーワードに続けて、結合対象のテーブルを指定します。2 つ目のテーブルを指定した後、ON キーワードと、以前のスタイルのクエリーで使用されていた結合条件を指定します。現在 ANSI 結合となった、元の形式のクエリーを次に示します。

 
SELECT   e.emp_id,
         e.fname,
         e.lname,
         j.job_desc
FROM     employee AS e
JOIN     jobs AS j ON e.job_id = j.job_id
ORDER BY e.fname,
         e.lname
 
結合の種類
 

これらの問題は、ANSI 結合においては結合の種類を指定することによって解決します。また、シータ結合においては 等号とアスタリスク (=*) の組み合わせ (Microsoft SQL Server)、または プラス記号とアスタリスク (+*) の組み合わせ (Oracle) を使用することによって解決します。次に結合の種類ごとの動作を示します。

 
  • クロス結合
      2 つのテーブルに対して完全なクロス積を実行します。1 つ目のテーブルの各レコードが 2 つ目のテーブルのすべてのレコードと結合され、巨大な結果セットが生成されます。このコマンドでは、結合条件を指定しない場合と同じ結果が得られ、デカルト積とも呼ばれます。クロス結合を使用することはお勧めできません。クロス結合は、現在 Microsoft SQL Server でサポートされています。
  • 内部結合
      結合対象テーブルのいずれかに一致しない行がある場合、その行を破棄します。ANSI 結合で結合の種類が明示的に定義されていない場合は、デフォルトで内部結合が行われます。内部結合は、現在 Microsoft SQL Server、PostgreSQL、および MySQL でサポートされています。
  • 左 [外部] 結合
      JOIN ステートメントの左側に指定されているテーブルのすべてのレコードを返します。結合の左側のテーブルのレコードは、右側のテーブルに一致するレコードがない場合でも返されます。このとき、右側のテーブルの列は NULL 値を返します。次の例では、職種の説明 (job_desc) があるかどうかに関係なく、すべての従業員のレコードが返されます。多くの専門家は、一貫性の問題がない限りは、外部結合を左結合として記述することを推奨しています。左結合は、現在 Microsoft SQL Server でサポートされています。
  • 右 [外部] 結合
      JOIN ステートメントの左側に指定されているテーブルに一致するレコードない場合でも、右側のテーブルのすべてのレコードを返します。このとき、左側のテーブルの列は NULL 値を返します。次の例では、employee テーブルに一致するレコードがあるかどうかに関係なく、jobs テーブルのすべてのレコードが返されます。右結合は、現在 Microsoft SQL Server でサポートされています。
  • 完全結合
      他方のテーブルに一致するレコードがあるかどうかに関係なく、両方のテーブルのすべての行を返します。結果セットでは、結合の際にデータが存在しなかった部分は NULL 値で示されます。完全結合は、現在 Microsoft SQL Server でサポートされています。
 

ANSI 結合の場合、LEFT JOIN ではどちらのテーブルが左なのか、RIGHT JOIN ではどちらのテーブルが右なのかをクエリー自体が示しているため、シータ結合よりも分かりやすくなっています。

 

複数のキーを使用して複数のテーブルを結合するクエリーの構文は、基本的には同じ手法を拡張したものです。

 
複数のテーブルの結合例
 
--theta style query with multiple tables
SELECT   a.au_lname,
         a.au_fname,
         t2.title
FROM     authors a,
         titleauthor t1,
         titles t2
WHERE    a.au_id     = t1.au_id
  AND    t1.title_id = t2.title_id
ORDER BY t2.title

-- ANSI style query with multiple tables
SELECT   a.au_lname,
         a.au_fname,
         t2.title
FROM     authors a
JOIN     titleauthor AS t1 ON a.au_id     = t1.au_id
JOIN     titles      AS t2 ON t1.title_id = t2.title_id
ORDER BY t2.title
 
複数のキーを使用する結合の例
 
--theta style query with multipart key
SELECT   s1.store_id,
         s1.title_id,
         s2.qty
FROM     sales s1,
         sales_projections s2
WHERE    s1.store_id = s2.store_id
  AND  s1.title_id = s2.title_id
ORDER BY s1.store_id, s2.title_id

-- ANSI style query with multipart key
SELECT   s1.store_id,
         s1.title_id,
         s2.qty
FROM     sales s1
JOIN     sales_projections s2 ON s1.store_id = s2.store_id
   AND   s1.title_id = s2.title_id
ORDER BY s1.store_id, s2.title_id
 
WHERE 句
 

WHERE 句は、SELECT ステートメントの極めて重要な要素です。WHERE 句には、クエリーで不要なデータが返されないようにする検索条件のほとんどを指定できます。それ以外の検索条件は、この項で後述する HAVING 句で指定します。

 

WHERE 句の記述が適切でない場合、SELECT ステートメントの他の記述が正しくても適切な結果は得られません。したがって、WHERE 句は細かな部分まで完全に理解しておく必要があります。複数の条件からなる WHERE 句を持つ典型的なクエリーの例を次に示します。

 
SELECT   a.au_lname,
         a.au_fname,
         t2.title,
         convert(char,t2.pubdate)
FROM     authors a
JOIN     titleauthor t1 ON a.au_id = t1.au_id
JOIN     titles t2 ON t1.title_id = t2.title_id
WHERE    (t2.type = 'business' OR t2.type = 'popular_comp')
  AND    t2.advance > $5500
ORDER BY t2.title
 

この例では、演算子の優先順位に従った WHERE 条件の処理順位が、かっこによって変更されています。

 

データベースのデフォルトのソート順序によって、クエリーの結果セットを WHERE 句がどのように取り出すかが決まります。たとえば、Microsoft SQL Server はデフォルトで辞書順および大文字小文字を区別しないに設定されており、"Smith"、"smith"、"SMITH" を区別しません。しかし Oracle は辞書順および大文字小文字を区別するを使用しており、"Smith"、"smith"、"SMITH" を異なる値として扱います。

 

WHERE 句には、この例に示した機能の他に、さらに詳細な機能があります。表 3.9 に、WHERE 句の一般的な機能の概要を示します。

 
検索条件の概要構文使用方法と説明
単純なブール値チェック
WHERE [NOT] expression
comparison_operator  expression
SELECT au_id
FROM   authors
WHERE  au_id = '172-32-1176'

SELECT au_id
FROM   authors
WHERE  au_lname NOT LIKE 'John%'
<、>、<>、>=、<=、および = の各演算子を使用して式 (expression) を比較できます。他にも、LIKE などの特殊な比較演算子がいくつかあります。これらについてはこの表で後述します。NOT キーワードは、通常の演算子 (<、>、<>、>=、<=、および =) と特殊な演算子 (LIKENULLBETWEENINEXISTSANY、および ALL) に基づくブール値チェックの逆をチェックします。
複数の検索条件
WHERE [NOT] expression
comparison_operator expression
{AND | OR}
expression comparison_operator
expression
SELECT au_id
FROM   authors
WHERE  au_id = '172-32-1176'
  AND  au_lname = 'White'
AND は複数の条件を結合し、両方の条件が true の場合に結果を返します。AND はその他の演算子よりも優先されます。WHERE 句でかっこを使用すると、演算子の優先順序に影響を与えることができます。OR は複数の条件を結合し、いずれかの条件が true の場合に結果を返します。ORAND の次に優先されます。
NULL チェック
WHERE [NOT] column_name IS [NOT]
NULL
SELECT *
FROM   titles
WHERE  price IS NULL
IS NULL は NULL 値をチェックし、IS NOT NULL は NULL 値以外のすべての値をチェックします。
JOIN チェック
WHERE [NOT] column_value(s)
[(+)]=[(+)] column_value(s)
または
WHERE [NOT] column_value(s)
[*]=[*] column_value(s)
SELECT a.au_lname,
       a.au_fname,
       t2.title
FROM  authors a,
      titleauthor t1,
      titles t2
WHERE a.au_id = t1.au_id
  AND t1.title_id = t2.title_id
ORDER BY t2.title
JOIN チェックは、複数のテーブル間の共通キーを評価することで行います。PostgreSQL で外部結合を行うには、すべてのレコードが取得される側にアスタリスクを指定します。Oracle で外部結合を行うには、NULL 値を許可する側にかっこで囲んだプラス記号 (+) を指定します。これは、基本的なアスタリスク指定方法とは異なります。詳細については、前の JOIN の項を参照してください。
LIKE チェック
WHERE [NOT] column_name [NOT]
LIKE 'match_string'
/* get any phone number starting with 415 */
SELECT * FROM authors
WHERE phone LIKE '415%'
LIKE は、引用符で囲んだ文字列に対するパターンマッチングを行います。使用できるワイルドカード記号については、LIKE の説明を参照してください。
EXISTS チェック
WHERE [NOT] EXISTS (subquery)
SELECT p1.pub_name
FROM publishers p1
WHERE EXISTS
    (SELECT *
    FROM titles t1
    WHERE pub_id =p1.pub_id
      AND type =
      'psychology')
EXISTS は、常にサブクエリーと共に使用されます。この場合、サブクエリーはデータを返すのではなく、データが存在するかどうかのブール値チェックを行います。この例は、心理学 (psychology) に関する書籍を発行しているすべての出版社 (pub_name) を返します。
BETWEEN 範囲チェック
WHERE [NOT] expression [NOT] BETWEEN expression AND expression
SELECT *
FROM titles
WHERE ytd_sales BETWEEN 4000 AND 9000
BETWEEN は、対象が範囲に含まれているかどうかをチェックします。これは、WHERE (expression>= x and expression<= y) と同じです。
IN 範囲チェック
WHERE [NOT] expression [NOT] IN
(value_list | subquery)
SELECT *
FROM stores
WHERE state IN ('WA','IL','NY')

SELECT *
FROM stores
WHERE stor_id IN
  (SELECT stor_id
  FROM sales
  WHERE ord_date LIKE
  'Oct%')
IN は、値のリストのいずれかに一致する結果セットを返すか、またはサブクエリーで返された値に一致する外側のクエリーの結果セットを返します。値のリスト (value_list) とサブクエリーはかっこで囲む必要があります。
SOME | ALL 範囲チェック
WHERE [NOT] expression
comparison_operator
{[ANY | SOME] | ALL} (subquery)
-- to duplicate the functionality of IN
SELECT au_lname,
       au_fname
FROM   authors
WHERE city = ANY
    (SELECT city
     FROM   publishers)
-- to duplicate the functionality of NOT IN
SELECT au_lname,
       au_fname
FROM authors
WHERE city <> ALL
    (SELECT city
     FROM   publishers)
/* to find the titles that got an
advance larger than the minimum
advance amount paid New Moon Books*/
SELECT title
FROM   titles
WHERE  advance > ANY
    (SELECT  advance
     FROM publishers,
      titles
     WHERE titles.pub_id =
       publishers.pub_id
     AND pub_name = 'New
       Moon Books')
ALLSOME は、常にサブクエリーおよび比較演算子 (<、>、<>、>=、<= など) と共に使用されます。ALL を使用するクエリーは、サブクエリーで取得されたすべての値が WHERE (または HAVING) 句の値と一致する場合に TRUE を返し、サブクエリーが外側のステートメントの行を返さない場合に FALSE を返します。SOME の機能は EXISTS と同じです。このオプションは ALL と同じように機能しますが、サブクエリーで取得されたいずれかの値が、外側のステートメントの WHERE 句に指定された比較述語を満たす場合に TRUE と評価する点が異なります。
 

表 3.9 に示したように、 ワイルドカード文字を使用して検索オプションを拡張できます。ワイルドカード文字は、特に LIKE 演算子で使用すると便利です。ワイルドカード文字の種類の詳細については、LIKE の説明を参照してください。

 
集計と GROUP BY 句
 

GROUP BY 句 (および HAVING 句) は、本章で既に説明した集計関数を利用するクエリーでのみ必要になります。クエリーで集計関数を使用すると、さまざまな集計情報を得ることができます。次に一般的な集計関数を示します。

 
  1. AVG は、指定した列に含まれるすべての非 NULL 値の平均を返します。
  2. COUNT は、指定した列に含まれるすべての非 NULL 値の数をカウントします。
  3. COUNT DISTINCT は、指定した列に含まれるすべての非 NULL の個別値の数をカウントします。
  4. COUNT(*) は、テーブルに格納されている全レコードの数をカウントします。
  5. MAX は、指定した列に含まれる非 NULL の最大値を返します。
  6. MIN は、指定した列に含まれる非 NULL の最小値を返します。
  7. SUM は、指定した列に含まれるすべての非 NULL 値を合計します。
 

使用できる集計関数は、対象となる列のデータタイプによって制限されます。任意のデータタイプの列に対して使用できるのは、COUNTCOUNT DISTINCT だけです。MINMAX は、任意のデータタイプの数値列、日付データタイプの列、および文字列データタイプの列に対して使用できます。SUMAVG は、数値データタイプの列に対してのみ使用できます。

 

NULL 値を含む列に対して集計関数を実行する必要がある場合は、ISNULL( ) 関数 (SQL Server の場合) または NVL 関数 (Oracle の場合) を使用して NULL 値に値を代入します。

 

単一の値を返すクエリーは、スカラー集計と呼ばれます。スカラー集計では、GROUP BY 句は不要です。次に例を示します。

 
--Query
SELECT AVG(price)
FROM titles

--Results
14.77
 

通常の列値と集計関数の両方を返すクエリーは、一般的にベクトル集計と呼ばれます。ベクトル集計は GROUP BY 句を使用し、1 行または複数の行を返します。GROUP BY 句を使用する際は、次の規則に従う必要があります。

 
  1. GROUP BY 句は、WHERE 句の後、ORDER BY 句の前に配置します。
  2. すべての非集計列を GROUP BY 句に指定します。
  3. GROUP BY 句で列エイリアスを使用することはできません。テーブルエイリアスは使用できます。
 

次の例は、社内における職種 (job_desc) 別の従業員の数を調べます。

 
--Query
SELECT   j.job_desc AS "Job Description",
         COUNT(e.job_id) AS "Nbr in Job"
FROM     employee e
JOIN     jobs j ON e.job_id = j.job_id
GROUP BY j.job_desc

--Results
Job Description                                    Nbr in Job
-------------------------------------------------- -----------
Acquisitions Manager                               4
Business Operations Manager                        1
Chief Executive Officer                            1
Chief Financial Officer                            1
Designer                                           3
Editor                                             3
Managing Editor                                    4
Marketing Manager                                  4
Operations Manager                                 4
Productions Manager                                4
Public Relations Manager                           4
Publisher                                          7
Sales Representative                               3
 
HAVING 句
 

HAVING 句は、GROUP BY 句の結果に検索条件を設定します。HAVING 句は、集計に使用される行には作用しません。クエリーで返される行にのみ作用します。

 

HAVING 句の動作は、WHERE 句の動作とよく似ています。HAVING 句では、表 3.9 で説明した WHERE 句の検索条件をすべて使用できます。

 

たとえば、4 人以上の従業員が割り当てられている職種 (job_desc) を調べるには次のようにします。

 
--Query
SELECT   j.job_desc "Job Description",
         COUNT(e.job_id) "Nbr in Job"
FROM     employee e
JOIN     jobs j ON e.job_id = j.job_id
GROUP BY j.job_desc
HAVING   COUNT(e.job_id) > 3

--Results
Job Description                                    Nbr in Job
-------------------------------------------------- -----------
Acquisitions Manager                               4
Managing Editor                                    4
Marketing Manager                                  4
Operations Manager                                 4
Productions Manager                                4
Public Relations Manager                           4
Publisher                                          7
 

HAVING 句は、WHERE 句で排除できる行を排除するために使用しないでください。HAVING 条件には、必ず集計値を含める必要があります。

 
ORDER BY 句
 

ORDER BY 句を使用すると、データベースのソート順序に従って結果セットをソートできます。結果セットは、昇順 (ASC) または降順 (DESC) のどちらでもソートできます。デフォルトは昇順です。次に例を示します。

 
--QUERY
SELECT   e.emp_id "Emp ID",
         rtrim(e.fname) || " " || rtrim(e.lname) "Name",
         j.job_desc "Job Desc"
FROM     employee e,
         jobs j
WHERE    e.job_id = j.job_id
  AND    j.job_desc = 'Acquisitions Manager'
ORDER BY e.fname DESC,
         e.lname ASC

--RESULTS
Emp ID    Name                           Job Desc
--------- ------------------------------ --------------------
M-R38834F Martine Ranc                  Acquisitions Manager
MAS70474F Margaret Smith                 Acquisitions Manager
KJJ92907F Karla Jablonski                Acquisitions Manager
GHT50241M Gary Thomas                    Acquisitions Manager
 

結果セットは、検索条件に従って絞り込まれた後、著者の姓 (lname) を基準に降順でソートされています。複数の著者の姓が同じである場合は、著者の名 (fname) を基準に昇順でソートされます。

 

すべての実装では、ORDER BY 句で列番号を使用することもできます。列名または列エイリアスの代わりに、列の位置を表す整数で結果セットのソート順序を指定できます。たとえば、au_idau_fname、そして最後に au_lname を基準にソートするには、次のようにします。

 
SELECT au_fname, au_lname, au_id
FROM authors
ORDER BY 3, 1, 2
 

通常は、ORDER BY 句を使用してクエリーの結果セットの順序を制御します。ORDER BY 句を指定しない場合、ほとんどの実装では、テーブル内でのデータの物理順序、またはクエリーが使用したインデックスの順序に従ってデータが返されます。そのため、インデックスまたはデータの物理ソート順序が変更された場合に問題が生じる可能性があります。したがって、明示的に順序を指定することをお勧めします。

 
Microsoft SQL Server の構文およびバリエーション
 

Microsoft SQL Server の SELECT ステートメントには、オプティマイザヒント、INTO 句、TOP 句、GROUP BY の拡張、COMPUTEWITH OPTIONS など、いくつもの変更が加えられています。

 
SELECT . . . INTO
 
SELECT select_list
INTO   new_table_name
FROM   table_source
WHERE  clause
 

SELECT . . . INTO は SQL Server 独自のコマンドオプションで、一部で議論の的になっています。SELECT . . . INTO コマンドを使用すると、あるテーブルからクエリーで取得した行および列を、新しいテーブルに簡単にコピーできます。この操作はログには記録されません。

 

次の例は、SELECT . . . INTO を使用して non_mgr_employees というテーブルを作成します。このテーブルには、employee テーブルに格納されているマネージャ以外の従業員の emp_id、名 (fname)、および姓 (lname) と、jobs テーブルから取得した職種の説明 (job_desc) を結合して格納します。

 
--QUERY
SELECT   e.emp_id "emp_id",
         convert(char(25),rtrim(e.fname) + " " + rtrim(e.lname)) "name",
         substring(j.job_desc,1,30) "job_desc"
INTO     non_mgr_employee
FROM     employee e
    JOIN jobs AS j ON e.job_id = j.job_id
WHERE    j.job_desc NOT LIKE '%MANAG%'
ORDER BY 2,3,1
 

新たに作成および読み込まれた non_mgr_employee テーブルに対し、クエリーを発行できます。このテーブルに対し、簡単なクエリーを発行してデータを取得します。

 
--QUERY
SELECT   emp_id,
         name,
         job_desc
FROM     non_mgr_emp
ORDER BY 3,2,1

--RESULTS
emp_id    name                      job_desc
--------- ------------------------- ------------------------------
PTC11962M Philip Cramer             Chief Executive Officer
F-C16315M Francisco Chang           Chief Financial Officer
<...edited for brevity...>
PMA42628M Paolo Accorti             Sales Representative
TPO55093M Timothy O'Rourke          Sales Representative
 

SELECT . . . INTO は、開発用または非公開用のコードでの使用にとどめることを強くお勧めします。

 
TOP 句
 

TOP 句の構文を次に示します。

 
SELECT [TOP n [PERCENT] [WITH TIES]] select list
FROM table_name
 

このコマンドは、クエリーの結果セットに先頭 n 行のみを取得するよう指定します。パーセンテージ (PERCENT) も指定した場合は、行全体の最初の n% が取得されます。WITH TIES キーワードは、ORDER BY 句が指定されたクエリーでのみ使用できます。このキーワードは、基本の結果セットから、ORDER BY 句に指定した列の値が TOP 句の最終行と同じである行をすべて返すように指定します。

 
GROUP BY の拡張
 

Microsoft SQL Server の GROUP BY は、ALLWITH CUBE、および WITH ROLLUP をサポートしています。

 
[ GROUP BY [ALL] group_by_expression [,...n]
[ WITH { CUBE | ROLLUP } ] ]
 

ALL は、WHERE 句のフィルタに一致する行を持たないグループを含め、すべてのグループを結果セットに含めるよう強制します。ALL は、CUBE または ROLLUP と併用することはできません。CUBE は、結果セットと共に、グループおよびサブグループの組み合わせごとの集計行を取得するよう指定します。ROLLUPCUBE と似ていますが、集計された階層順序 (グループ内の最下位レベルから最上位レベルへの順) でグループを返す点が異なります。

 
COMPUTE 句
 

COMPUTE 句は合計を生成し、これを集計列として結果セットの末尾に追記します。COMPUTE BY 句は、結果セット内に制御の切れ目と小計を生成します。同じクエリーの中に COMPUTE BYCOMPUTE の両方を指定できます。

 
[ COMPUTE { { AVG | COUNT | MAX | MIN | STDEV | STDEVP |VAR | VARP | SUM }
(expression) } [,...n]
[ BY expression [,...n] ] ]
 

各引数 (AVGCOUNTMAXMINSTDEVSTDEVPVARVARPSUM) は、COMPUTE 句で実行する集計の種類を指定します。通常、expression には列の名前を指定します。BY expression には、クエリーの ORDER BY 句に指定されている列を指定できます。COMPUTE 句は、クエリーの ORDER BY 句の後に記述します。

 
OPTION 句
 

OPTION 句は、Microsoft SQL Server のクエリーの中で最後に指定する句です。この句は、クエリー全体を通してクエリーヒントを使用するよう指定します。クエリーヒントは、クエリーのデフォルトの処理方法より優先される非 ANSI 規格の手法です。クエリーヒントと OPTION 句の完全な構文およびその用法については、本マニュアルでは扱いません。詳細については SQL Server のマニュアルを参照してください。

 
MySQL の構文およびバリエーション
 
SELECT [STRAIGHT_JOIN][SQL_SMALL_RESULT][SQL_BIG_RESULT][HIGH_PRIORITY]
[INTO {OUTFILE | DUMPFILE} 'file_name' options]
FROM...
JOIN...
[LIMIT [[offset_record,] number_of_rows]];
 

MySQL の拡張には、デフォルトの SELECT キーワードに対する変更、JOIN の一部サポート、LIMIT 句、および PROCEDURE 句があります。

 

デフォルトの SELECT 句に対する 1 つ目の拡張は、STRAIGHT_JOIN です。STRAIGHT_JOIN は、FROM 句に指定されたとおりの順序でテーブルを結合するようオプティマイザに強制します。SQL_SMALL_RESULTSQL_BIG_RESULT はそれぞれ、小さい結果セットまたは大きい結果セットにするようオプティマイザに指示します。これらは、クエリーに GROUP BY 句または DISTINCT 句が含まれている場合に使用できます。クエリーに DISTINCT 句または GROUP BY 句が含まれている場合、MySQL は一時テーブルを作成します。これらのオプション句は、ワークテーブルを処理するために、MySQL に対してメモリー内に高速な一時テーブルを作成するよう指示したり (SQL_SMALL_RESULT の場合)、低速なディスクベースの一時テーブルを作成するよう指示したり (SQL_BIG_RESULT の場合) します。HIGH_PRIORITY は、クエリーに対し、テーブル内のデータを変更するステートメントよりも高い優先順位を与えます。この句は、特別な高速クエリーに対してのみ使用します。LIMIT 句は、クエリーによって返される行の数を制限します。offset_record の位置から returning number_of_rows 個の行が返されます。指定した整数が 1 つだけの場合、その数が必要なレコードの数と見なされ、デフォルトのオフセットは 0 と見なされます。

 

SELECT . . . INTO OUTFILE `file_name' 句は、クエリーの結果セットをホストファイルシステム上のファイルに書き込みます。既存のファイルを file_name に指定することはできません。SELECT . . . INTO DUMPFILE は、列の区切り、行の区切り、およびエスケープ文字なしで、1 つの連続した行としてデータを書き込みます。このオプションは、主に BLOB ファイル用に使用します。

 

MySQL がサポートする JOIN の構文は、次のタイプのみです。

 
[CROSS JOIN]
INNER JOIN
STRAIGHT_JOIN
LEFT [OUTER] JOIN
NATURAL LEFT [OUTER] JOIN
 
Oracle の構文およびバリエーション
 
SELECT {[ALL] [DISTINCT] | [UNIQUE]}...
{columns_and_expressions_list} [,...n] AS alias
[INTO {variable[,...n] | record}]
FROM {[table_name [@database_link]| view_name | snapshot_name]
   | subquery [WITH {READ ONLY | CHECK OPTION [CONSTRAINT constraint_name]}]
   | TABLE {(nested_tbl_column)}
      [PARTITION {partition_name}]
      [SUBPARTITION {subpartition_name}
         [SAMPLE [BLOCK] [sample_percentage]}
WHERE
[[START WITH clause] CONNECT BY clause]
GROUP BY...
[ORDER BY... [NULLS FIRST | NULLS LAST] |
 FOR UPDATE [OF [schema.]table[,...n]] [NOWAIT] ]
 

Oracle では、サーバー内部の SELECT サポート追加機能に対して、いくつかの拡張を加えることができます。たとえば、ネストしたテーブルとパーティションテーブルの両方を作成できるので (CREATE TABLE の説明を参照)、SELECT ステートメントでこれらのテーブルを明示的に指定してクエリーを実行できます。デフォルトパーティションに対してクエリーを実行する場合、PARTITION 句は不要です。

 

SAMPLE 句を指定すると、テーブル全体からではなく、結果セット内でランダムにサンプリングされた行からレコードが選択されます。SAMPLE BLOCK 句を指定すると、行サンプリングではなくブロックサンプリングが行われます。sample_percentage には、サンプルに含めるブロック数または行数のパーセンテージを 0.000001 ~ 99 で指定します。サンプリングは、単一テーブルに対するクエリーでのみ行うことができます。

 

SELECT . . . INTO 構文は、PL/SQL コードでのみ使用できます。この構文を使用すると、SELECT ステートメントで変数に値を代入できます。

 

ネストしたテーブルに対してクエリーを実行する場合は、FROM TABLE nested_table_column 句を使用する必要があります。@database_link 句を使用すると、db_link として宣言されている他のデータベースまたはサーバーに格納されているテーブルにクエリーでアクセスできます。db_link の詳細については、ベンダーのマニュアルを参照してください。

 

ORDER BY 句に NULL FIRST オプションまたは NULL LAST オプションを付けると、そのオプションに応じて、NULL を含む行が結果セットの先頭または末尾に表示されます。

 

Oracle では、結果セットを階層順序で表示するよう指定できます。これらのいわゆる階層クエリーにはさまざまな規則があり、独特の動作をします。この種のクエリーの使用上の規則については、ベンダーのマニュアルを参照してください。START WITH 句は階層クエリーに必須の句で、階層のルート行を指定します。CONNECT BY 句には、階層内の親行と子行の関係を記述します。

 

FOR UPDATE OF 句は、クエリーで返される行を排他的にロックします。この句の直後には、UPDATE . . . WHERE コマンドと、COMMIT または ROLLBACK を指定する必要があります。NOWAIT オプションは、目的のレコードが既にロックされている場合には待機しないよう指示します。レコードが既にロックされていた場合、クエリーは終了し、直ちに制御がユーザーに返されます。

 
PostgreSQL の構文およびバリエーション
 
SELECT...
[INTO [TEMPORARY | TEMP] [TABLE] new_table_name]
FROM...
WHERE...
[FOR UPDATE [OF class_name[,...n]]
[LIMIT {count | ALL} [offset [,number_of_records]] ]
 

PostgreSQL では、SELECT . . . INTO 構文を使用して新しいテーブルを作成できます。これは、基本的には Microsoft SQL Server でサポートされているものと同じです。FOR UPDATE 句は、クエリーで選択されたレコードを排他的にロックします。また MySQL と同様に、クエリーで返される行数を制限する LIMIT 句もサポートされています。

 
SET CONNECTION 

SET CONNECTION ステートメントを使用すると、データベースサーバーに対して開かれている複数の接続を切り替えることができます。

 
ベンダーコマンド
SQL Server制限付き対応
MySQL未対応
Oracle未対応
PostgreSQL未対応
 
SQL99 の構文および説明
 
SET CONNECTION {DEFAULT | connection_name}
 

これは、接続を終了するコマンドではありません。このコマンドは、現在の接続からコマンドに指定された接続に切り替えるか、または DEFAULT 句を使用して現在の接続に切り替えるために使用します。接続を切り替える際、古い接続は変更を一切コミットすることなく休止状態になり、新しい接続がアクティブになります。

 

新しい接続を作成する場合は CONNECT コマンドを使用し、接続を終了させる場合は DISCONNECT コマンドを使用する必要があります。

 
Microsoft SQL Server の構文およびバリエーション
 

Microsoft SQL Server は、Embedded-SQL (ESQL) でのみ SET CONNECTION をサポートし、その検索ツールの SQL Query Analyzer ではサポートしていません。ESQL では SQL99 の構文を完全にサポートしています。

 
 

SQL Server の完全な ESQL プログラムでの CONNECTDISCONNECT、および SET CONNECTION の使用例を次に示します。

 
EXEC SQL CONNECT TO chicago.pubs AS chicago1 USER sa;
EXEC SQL CONNECT TO new_york.pubs AS new_york1 USER read-only;
// opens connections to the servers named "chicago" //
//   and "new_york"//

EXEC SQL SET CONNECTION chicago1;
EXEC SQL SELECT name FROM employee INTO :name;
// sets the chicago1 connection as active and performs work //
//   within that session //

EXEC SQL SET CONNECTION new_york1;
EXEC SQL SELECT name FROM employee INTO :name;
// sets the new_york1 connection as active and performs work //
//   within that session //

EXEC SQL DISCONNECT ALL;
// Terminates all sessions.  You could alternately use two //
//   DISCONNECT commands, one for each named connection. //
 
SET ROLE 

SET ROLE コマンドは、現在のセッションで特定のセキュリティロールを有効または無効にします。セッションは CONNECT ステートメントを使用して作成し、ロールは CREATE ROLE ステートメントを使用して作成します。

 
ベンダーコマンド
SQL Server未対応
MySQL未対応
Oracle変則対応
PostgreSQL未対応
 
SQL99 の構文および説明
 
SET ROLE {NONE | role_name}
 

セッションは、CONNECT ステートメントを使用して開始します。ユーザーセッションが開始された後、SET ROLE ステートメントを発行すると、ロールに関連付けられた権限のセットがそのセッションに付与されます。SET ROLE コマンドは、トランザクションの外部からのみ発行できます。

 

SET ROLE NONE は、現在のセッションを NULL ロールに割り当てます。

 

現在アクティブなユーザーセッションにロールが割り当てられている場合は、文字列、データベース変数、さらには CURRENT_ROLESYSTEM_ROLE などのシステム関数を使用できます。いずれの場合でも、指定する値は有効なロール名でなければなりません。

 
Oracle の構文およびバリエーション
 
SET ROLE {role_name [IDENTIFIED BY password] [,...n]
| [ALL [EXCEPT role_name [,...]]
|  NONE;
 

ユーザーが接続を開始すると、Oracle は明示的に権限 (ロール) をユーザーに割り当てます。そのセッションが実行されるロールは、SET ROLE コマンドで変更できます。Oracle では、MAX_ENABLED_ROLES 初期化パラメータを使用して、同時に開くことのできるロールの最大数を制御します。

 

指定するロール名 (role_name) は、Oracle 内に作成済みの有効なロール名でなければなりません。指定されていないロールを現在のセッションで利用することはできません。role_name にパスワードが設定されている場合は、IDENTIFIED BY password 句を使用してそのパスワードを記述する必要があります。複数の ロールを指定する場合は、各ロールをコンマで区切ります。

 

SET ROLE ALL ステートメントは、現在のセッションに付与されているすべてのロールを有効にします。これには、他のロールを介して付与されているロールも含まれます。EXCEPT 句を使用すると、対象外とするロールを指定できます。SET ROLE ALL は、パスワードを指定する必要がある場合には使用できません。パスワードの設定されたロールにアクセスするには、SET ROLE role_name IDENTIFIED BY password ステートメントを使用する必要があります。

 

SET ROLE NONE ステートメントは、デフォルトロールを含め、すべてのロールを無効にします。

 
 

現在のセッション用に、それぞれパスワード editorred_marker で識別される read_only ロールと updater ロールを有効にするには次のコマンドを実行します。

 
SET ROLE read_only IDENTIFIED BY editor, updater IDENTIFIED BY red_marker;
 

read_write ロールを除くすべてのロールを有効にします。

 
SET ROLE ALL EXCEPT read_write;
 
SET TIME ZONE 

SET TIME ZONE ステートメントは、現在のセッションのタイムゾーンをデフォルトとは別のタイムゾーンに変更します。

 
ベンダーコマンド
SQL Server未対応
MySQL未対応
Oracle未対応
PostgreSQL変則対応
 
SQL99 の構文および説明
 
SET TIME ZONE {LOCAL | INTERVAL {+ | -}'00:00' HOUR TO MINUTE}
 

ほとんどの SET コマンドと同様に、SET TIME ZONE は明示的なトランザクションの外部からのみ実行できます。LOCAL 句は、現在のセッションの時刻値をサーバーのデフォルトタイムゾーンの時刻値に設定します。または INTERVAL を使用して、デフォルトの時刻を増減 (+ または -) する間隔値を設定することもできます。

 
PostgreSQL の構文およびバリエーション
 
SET TIME ZONE {'timezone' | LOCAL | DEFAULT
| INTERVAL {+ | -}'00:00' HOUR TO MINUTE};
 

PostgreSQL では、LOCAL 句または DEFAULT 句を使用してセッションの時刻値をサーバーのデフォルトに設定できます。

 

タイムゾーンに指定する値は、オペレーティングシステムによって異なります。たとえば、`PST8PDT' は Linux システムでのカリフォルニアのタイムゾーンとして有効です。また、`Europe/Rome' は Linux およびその他システムでのイタリアのタイムゾーンとして有効です。無効なタイムゾーンが指定された場合、タイムゾーンはグリニッジ標準時 (GMT) に設定されます。

 

タイムゾーンは、サーバーのデフォルトタイムゾーンとの間隔として設定することもできます。

 
 

次の例では、現在のデフォルトタイムゾーンを 3 時間進めたタイムゾーンに設定しています。

 
SET TIME ZONE INTERVAL +'03:00' HOUR TO MINUTE;
 

次に、現在のセッションの現在の時刻を 4 時間半遅らせています。

 
SET TIME ZONE INTERVAL -'04:30' HOUR TO MINUTE;
 

そして、現在のセッションの時刻をデフォルトに戻しています。

 
SET TIME ZONE LOCAL;
 
SET TRANSACTION 

SET TRANSACTION ステートメントは、データの読み取りや書き込み、またはその隔離レベルなど、データ変更に関する多くの特性を制御します。

 
ベンダーコマンド
SQL Server変則対応
MySQL未対応
Oracle制限付き対応
PostgreSQL対応
 
SQL99 の構文および説明
 
SET [LOCAL] TRANSACTION { {READ ONLY | READ WRITE}[,...]
| ISOLATION LEVEL
  {READ COMMITTED
  | READ UNCOMMITTED
  | REPEATABLE READ
  | SERIALIZABLE}[,...]
| DIAGNOSTIC SIZE INT};
 

このコマンドは、発行時にはトランザクションのコンテキスト外にありますが、次の有効なトランザクションに適用されます。コンマで区切ることで、複数のオプションを適用できます。

 

トランザクション設定をローカルサーバーにだけ適用する場合は、LOCAL コマンドを指定します。このオプションを指定しない場合は、トランザクションの実行場所に関係なくそのトランザクション設定が適用されます。このオプションは、SQL99 に新しく導入されたものです。

 

トランザクションは、読み取り専用 (READ ONLY) または読み書き用 (READ WRITE) として指定することもできます。DIAGNOSTIC SIZE 句に続けて整数を指定すると、1 つのトランザクションについて記録するエラーメッセージの数を指定できます。この情報は、GET DIAGNOSTICS ステートメントで取得できます。

 

ISOLATION LEVEL 句は、あるトランザクションにおける、同時トランザクションに影響するいくつかの動作を制御します。隔離レベルは、内容を保証しない読み込み非リピータブル読み込み、およびファントムレコードに関するトランザクションの動作を制御します。

 
  • 内容を保証しない読み込み
      あるトランザクションが、他のトランザクションが変更したレコードをそのトランザクションの完了前に読み込んだ場合に発生します。この場合、データベースにコミットされていない可能性のあるレコードに対するデータ変更が可能になってしまいます。
  • 非リピータブル読み込み
      あるトランザクションが、他のトランザクションが変更中のレコードを読み込んだ場合に発生します。この場合、前者のトランザクションがレコードを再読み込みしようとしても、そのレコードは見つからなくなります。
  • ファントムレコード
      あるトランザクションがレコードのグループを読み込んだ後にデータの追加や変更が行われ、そのトランザクションの条件を満たすレコードが増える結果になった場合に発生します。
 

隔離レベルの設定は、これらのデータ矛盾に関して、表 3.10 のような影響を与えます。

 
隔離レベル内容を保証しない読み込み非リピータブル読み込みファントムレコード
READ COMMITTED発生しない発生する発生する
READ UNCOMMITTED発生する発生する発生する
REPEATABLE READ発生しない発生しない発生する
SERIALIZABLE発生しない発生しない発生しない
 

SQL99 では、SERIALIZABLE がデフォルトの隔離レベルです。READ WRITE トランザクションでは、READ UNCOMMITTED に設定することはできません。

 
Microsoft SQL Server の構文およびバリエーション
 
SET TRANSACTION ISOLATION LEVEL
{READ COMMITTED
| READ UNCOMMITTED
| REPEATABLE READ
| SERIALIZABLE}
 

SQL99 のデフォルトは SERIALIZABLE ですが、SQL Server のデフォルトは READ COMMITTED です。隔離レベルは、SQL99 とは異なり、トランザクション単位ではなくセッション全体を通じて維持されます。

 
Oracle の構文およびバリエーション
 
SET TRANSACTION READ ONLY;
 

Oracle では、SET TRANSACTION ステートメントの完全な構文はサポートされていません。また、READ ONLY の実装にも若干の違いがあります。Oracle では、READ COMMITTEDSERIALIZABLE のみがサポートされています。デフォルトの動作は READ COMMITTED です。Oracle でこのコマンドを実行すると、トランザクションは隔離レベル SERIALIZABLE で開始されます。Oracle では、READ ONLYALTER SESSIONALTER SYSTEMLOCK TABLE、および SET ROLE の各コマンドが設定されている場合、実行できるのは SELECT コマンドのみになります。

 
PostgreSQL の構文およびバリエーション
 
SET TRANSACTION ISOLATION LEVEL {READ COMMITTED | SERIALIZABLE};
 

PostgreSQL では、SET TRANSACTION ステートメントの完全な構文はサポートされていません。PostgreSQL では、SET TRANSACTION ISOLATION LEVEL READ COMMITTED を指定すると、トランザクションの開始前に現在のトランザクションの読み取り専用行がコミットされます。これがデフォルトです。SERIALIZABLE (ANSI のデフォルト隔離レベル) を指定した場合は、バッチの中の最初のデータ変更が行われる前に、現在のトランザクションの読み取り専用行がコミットされます。

 
START TRANSACTION 

SQL99 で導入された START TRANSACTION ステートメントを使用すると、SET TRANSACTION のすべての機能を実行したり、新しいトランザクションを開始したりできます。

 
ベンダーコマンド
SQL Server未対応 (後述の BEGIN TRAN の項を参照)
MySQL未対応
Oracle未対応
PostgreSQL未対応 (後述の BEGIN TRAN の項を参照)
 
SQL99 の構文および説明
 
START TRANSACTION { {READ ONLY | READ WRITE}[,...]
| ISOLATION LEVEL
  {READ COMMITTED
  | READ UNCOMMITTED
  | REPEATABLE READ
  | SERIALIZABLE}[,...]
| DIAGNOSTIC SIZE INT};
 

SETSTART の違いは、SET は現在のトランザクションの外部と見なされ、START は新しいトランザクションが始まるマークと見なされるという点だけです。

 
BEGIN TRANSACTION
 

BEGIN TRANSACTION の機能は、START TRANSACTION と似ています。Microsoft SQL Server と PostgreSQL は、構文に多少の違いはありますが、どちらも BEGIN TRANSACTION をサポートしています。Oracle は、暗黙的なトランザクションはサポートしていますが、明示的なトランザクションはサポートしていません。MySQL は、アトミックトランザクションを一切サポートしていません。BEGIN TRANSACTION は、明示的なトランザクションを宣言しますが、隔離レベルは設定しません。

 

Microsoft SQL Server の構文

 
BEGIN TRAN[SACTION] [transaction_name | @transaction_variable
[WITH MARK [ 'log_description' ] ] ]
 

Microsoft SQL Server では、トランザクションに名前を割り当てたり、変数を使用してトランザクションを参照したりできます。これが機能に影響を与えることはありません。トランザクションをネストする場合、このトランザクション名 (トランザクション名がある場合) を参照する必要があるのは、最も外側にある BEGIN . . . COMMIT または BEGIN . . . ROLLBACK の組だけです。

 

WITH MARK オプションを指定すると、トランザクションが SQL Server のイベントログに記録されます。WITH MARK `log_description' と指定することで、ログに記録されるイベントに、そのイベントを説明する文字列を追記できます。

 

PostgreSQL の構文

 
BEGIN [ WORK | TRANSACTION ]
 

通常、PostgreSQL は自動コミットモードで実行されています。このモードでは、各データ変更やクエリーそれ自体がトランザクションとなります。PostgreSQL は通常、トランザクションの最後に COMMIT または ROLLBACK を暗黙的に適用します。BEGIN ステートメントを使用すると、次の COMMIT または ROLLBACK を明示的に宣言できます。

 

BEGIN は、COMMIT または ROLLBACK と対にして発行する必要があります。発行しない場合、DBMS は COMMIT または ROLLBACK が出現するまでコマンドを完了しません。これにより、予期せぬ結果をデータにもたらす巨大なトランザクションとなる可能性があります。

 

PostgreSQL では、手動で記述したトランザクションの方が、自動コミットされるトランザクションよりもはるかに高速です。トランザクションの隔離性を高めるため、BEGIN ステートメントの直後に SET TRANSACTION ISOLATION LEVELSERIALIZABLE に設定する必要があります。BEGIN . . . COMMIT ブロックには、数多くのデータ変更ステートメント (INSERTUPDATEDELETE) が指定される可能性があります。COMMIT コマンドを発行した場合、このコマンドが成功するか失敗するかによって、トランザクションがすべて実行されるか、またはまったく実行されないかのどちらかになります。

 
 

次の例では、3 つの INSERT ステートメントすべてが 1 つのトランザクションとして扱われます。

 
BEGIN TRANSACTION
   INSERT INTO sales VALUES('7896','JR3435','Oct 28 2001',25,
   'Net 60','BU7832')

   INSERT INTO sales VALUES('7901','JR3435','Oct 28 2001',17,
   'Net 60','BU7832')

   INSERT INTO sales VALUES('7907','JR3435','Oct 28 2001',6,
   'Net 60','BU7832')

COMMIT
GO
 

ただし、いずれかの INSERT ステートメントに主キー制約が含まれているなどの場合は、トランザクショングループ全体が失敗します。

 
TRUNCATE TABLE  

TRUNCATE TABLE コマンドは非 ANSI ステートメントで、テーブルのすべての行を削除します。個々の行削除はログには記録されません。テーブル構造を変更することなくすべてのレコードを簡単に消去することが可能で、さらに REDO ログやトランザクションログの領域をほとんど消費しないという非常に便利なコマンドです。ただしログに記録されないので、リカバリしたりバックアップしたりできないというデメリットもあります。

 
ベンダーコマンド
SQL Server対応
MySQL未対応
Oracle対応
PostgreSQL対応
 
SQL99 の構文および説明
 
TRUNCATE TABLE name
 

TRUNCATE TABLE ステートメントの機能は、WHERE 句を付けない DELETE ステートメントと同じです。どちらも、指定したテーブルの行をすべて削除します。ただし、大きな違いが 2 つあります。TRUNCATE TABLE はより高速である一方、ログに記録されません。つまり、エラーが発生してもロールバックはできません。

 

一般的に、TRUNCATE TABLE がトリガーを起動することはありません。また、指定したテーブルに外部キーが設定されている場合は機能しません。

 
 

次の例は、publishers テーブルのすべてのレコードを削除します。

 
TRUNCATE TABLE publishers
 
Oracle の構文およびバリエーション
 
TRUNCATE { CLUSTER [owner.]cluster
   | TABLE [owner.]table [{PRESERVE | PURGE} SNAPSHOT LOG]}
[{DROP | REUSE} STORAGE]
 

Oracle では、テーブルまたはインデックス付けされたクラスター (ハッシュクラスターを除く) を削除できます。

 

Oracle では、テーブルを削除する際、テーブルに定義されているスナップショットログを保持するか削除するかを指定できます。PRESERVE を指定すると、マスターテーブルを削除してもスナップショットログは保持されます。PURGE を指定した場合、スナップショットログは消去されます。

 

DROP STORAGE 句を付けた場合は、行の削除によって解放されたディスク領域の割り当てが解除されます。REUSE STORAGE 句を付けた場合は、テーブルまたはクラスターに割り当てられていた削除行の領域はそのまま保持されます。

 
Microsoft SQL Server と PostgreSQL
 

Microsoft SQL Server と PostgreSQL は、どちらも SQL99 のデフォルト構文をサポートしています。

 
UPDATE 

UPDATE コマンドは、テーブル内の既存データを変更します。

 
ベンダーコマンド
SQL Server変則対応
MySQL変則対応
Oracle変則対応
PostgreSQL対応
 
SQL99 の構文および説明
 
UPDATE {table_name | view_name}
SET {column_name | variable_name} = {DEFAULT | expression} [,...n]
WHERE conditions
 

DELETE ステートメントと同様、UPDATE コマンドは、ほとんどの場合 WHERE 句を付けて発行します。テーブルのすべての行に影響を与えるのを避けるためです。

 

実際に UPDATE ステートメントを発行する前に、同じ内容の WHERE 句を付けた SELECT コマンドを発行してみることをお勧めします。これによって、実際に UPDATE を行う前に結果セットのすべての行をチェックできます。この SELECT で返されたすべての行が UPDATE で変更されます。

 
 

WHERE 句を付けない基本的な UPDATE ステートメントを次に示します。

 
UPDATE authors
SET contract = 0
 

WHERE 句を付けない場合、authors テーブルのすべての著者の契約状況 (contract) が 0 に設定されます。つまり、いずれの著者も契約を持たない状態になります。同様に、UPDATE ステートメントで値を数学的に調整することもできます。

 
UPDATE titles
SET price = price * 1.1
 

この UPDATE ステートメントは、すべての書籍の価格 (price) を 10% 値上げします。

 

UPDATE ステートメントに WHERE 句を付け加えると、テーブル内の指定のレコードだけを変更できます。

 
UPDATE titles
SET    type  = 'pers_comp',
       price = (price * 1.15)
WHERE  type  = 'popular_com'
 

このクエリーは、種別 (type) が `popular_com' であるすべてのレコードに対し、2 つの変更を加えます。これらのレコードの価格 (price) を 15% 値上げし、その種別を `pers_comp' に変更します。

 

場合によっては、指定したテーブルの値を別のテーブルの値に基づいて更新しなければならないこともあります。たとえば、特定の著者の全著作の出版日 (pubdate) を更新する必要がある場合には、次のように、まずサブクエリーでその著者 (au_id) と著作 (title_id) のリストを検索しなければなりません。

 
UPDATE titles
SET    pubdate = 'Jan 01 2002'
WHERE  title_id IN
    (SELECT title_id
     FROM   titleauthor
     WHERE  au_id IN
         (SELECT au_id
          FROM   authors
          WHERE  au_lname = 'White'))
 
Microsoft SQL Server の構文およびバリエーション
 
UPDATE {table_name | view_name} [WITH (table_hint [,...n])]
SET {column_name | variable_name} = {DEFAULT | expression | NULL} [,...n]
[FROM {table [,...n]}]
WHERE {conditions | CURRENT OF [GLOBAL] cursor_name}
[OPTION (query_hint [,...n])]
 

Microsoft SQL Server では、ビューとテーブルの両方を更新できます。WITH table_hint 句と OPTION 句を使用して、テーブルレベルおよびクエリーレベルのオプティマイザヒントを宣言できます。オプティマイザヒントは、クエリーオプティマイザのデフォルトの機能より優先されます。オプティマイザヒントの詳細については、ベンダーのマニュアルを参照してください。

 

Microsoft SQL Server では、UPDATE ステートメントで FROM 句を使用できます。この拡張の主な利点は、複数テーブルの結合が容易になることです。テーブルの結合例を両スタイルの構文で次に示します。

 
-- ANSI style
UPDATE titles
SET    pubdate = GETDATE(  )
WHERE  title_id IN
    (SELECT title_id
     FROM   titleauthor
     WHERE  au_id IN
         (SELECT au_id
          FROM   authors
          WHERE  au_lname = 'White'))

-- Microsoft Transact-SQL style
UPDATE  titles
SET     pubdate = GETDATE(  )
FROM    authors a,
        titleauthor t2
WHERE   a.au_id     = t2.au_id
    AND t2.title_id = titles.title_id
    AND a.au_lname  = 'White'
 

Transact-SQL スタイルでの更新は、単純に authorstitles、および titleauthor の 3 つのテーブルを結合するだけで行うことができます。しかし、同じ操作を ANSI 準拠のコードで実行する場合は、まず authors テーブルで au_id を検索して titleauthor テーブルに渡し、このテーブルで title_id を確認してメインの UPDATE ステートメントに渡す必要があります。

 

WHERE CURRENT OF cursor_name 句にカーソルを指定した場合は、現在カーソルが位置している単一のレコードだけが更新されます。カーソルは、ローカルカーソルを指定することも、GLOBAL キーワードを使用してグローバルカーソルを指定することもできます。

 

次の例は、authors テーブルに格納されている著者のうち先頭 10 人の state 列を更新します。

 
UPDATE authors
SET state = 'ZZ'
FROM (SELECT TOP 10 * FROM authors ORDER BY au_lname) AS t1
WHERE authors.au_id = t1.au_id
 
MySQL の構文およびバリエーション
 
UPDATE [LOW PRIORITY] table_name
SET {column_name | variable_name} = {DEFAULT | expression}
WHERE conditions
[LIMIT integer]
 

MySQL は SQL99 標準をサポートしていますが、LOW PRIORITY 句と LIMIT 句という 2 つの拡張があります。LOW PRIORITY 句は、対象テーブルを読み込み中のクライアントがいなくなるまで UPDATE ステートメントの実行を待機するよう指示します。LIMIT 句は、UPDATE アクションの対象を整数値で指定された行数に制限します。

 
Oracle の構文およびバリエーション
 
UPDATE [schema.]{view_name | snapshot_name
   | table_name [@database_link]
      {[PARTITION partition_name] | [SUBPARTITION subpartition_name]}
   | subquery [WITH {[READ ONLY]
      | [CHECK OPTION [CONSTRAINT constraint_name] ]
SET {column [,...] = {expression [,...n] | subquery} | VALUE value}
WHERE conditions | CURRENT OF cursor_name}
RETURNING expression [,...n] INTO variable [,...n];
 

Oracle による UPDATE の実装では、許可されたスキーマ内のビュー、スナップショット、およびテーブルを更新できます。更新できるテーブルは、ローカルテーブルまたは @dblink を介してアクセス可能なテーブルです。更新は、常にパーティションに対して行われます。ただし、UPDATE コマンドは、指定のパーティション (PARTITION) またはサブパーティション (SUBPARTITION) に対する更新をサポートしています。

 

サブクエリーに対して更新を行う場合は、WITH 句を使用できます。WITH READ ONLY 句は、サブクエリーを更新できないように指定します。WITH CHECK OPTION は、更新対象テーブルに対する変更のうち、サブクエリーの結果セットに含まれないレコードに対する変更は行わないよう指示します。CONSTRAINT 従属句は、特定の制約に基づいてさらに変更を制限するよう指示します。

 

SET VALUE 句を使用すると、行値全体を任意のデータタイプ値に設定できます。

 

Oracle の WHERE CURRENT OF 句は、そのカーソルコンテキスト内の現在のレコードに対してのみ UPDATE を実行するよう指定します。

 

RETURNING は、コマンドの影響を受ける行を取得します。単一行の更新に使用した場合、その行の値を PL/SQL 変数およびバインド変数に格納できます。複数行の削除に使用した場合、それらの行の値はバインド配列に格納されます。INTO キーワードを指定すると、更新された値が変数リストに格納されます。

 
PostgreSQL
 

PostgreSQL は SQL99 標準をサポートしています。UPDATE コマンドの詳細については、前述の項を参照してください。