列に対してフォーマット句を指定した場合、基となるドメインもフォーマット句を指定するものである場合、表定義のフォーマット句がドメイン定義のフォーマット句をオーバーライドします。
SQLでは、列の制約と表の制約が可能です。「使用方法」では、2種類の制約の相違をまとめています。表制約には、PRIMARY KEY、UNIQUE、CHECKおよびFOREIGN KEY制約の4つのタイプがあります。
表制約定義に列を指定するには、最初に表に列を定義する必要があります。
表制約は、永続実表およびグローバル一時表に対してのみ定義できます。
算出列やLIST OF BYTE VARYINGデータ型で定義された列には、UNIQUE制約を指定できません。
- 表を作成するには、データベースに対するCREATEデータベース権限が必要です。LIKE句で指定された表に対して、REFERENCEデータベース権限が必要です。
- CREATE TABLE文を実行すると、SQLでデータベースに表定義が追加されます。
PATHNAME指定でデータベースを宣言すると、定義もリポジトリに追加されます。- リポジトリを使用してレコード構造を定義する際、その構造がOracle Rdbで許容されない可能性があります。
リポジトリは、多くのレイヤー製品および言語で使用可能なデータ構造体を保持できる汎用データ・リポジトリとされています。
このようなデータ構造体は、Oracle Rdbが使用するリレーショナル・データ・モデルに適用する際は、必ずしも有効でない場合があります。
リポジトリのデータ構造体とOracle Rdb間の一般的な非互換性には、次のものがあります。
- %CDD-E-PRSMISSNG, attribute value is missing
このエラーは、リポジトリのレコード定義にVARIANTS句が含まれていると発生する場合があります。- %CDD-E-INVALID_RDB_DTY, data type of field is not supported by Oracle Rdb
このエラーは、リポジトリのレコード定義にOCCURS句が含まれていると発生する場合があります。- %CDD-E-DTYPE_REQUIRED, field must have a data type for inclusion in an Oracle Rdb database
このエラーは、リポジトリのレコード定義に別のネストされたレコード定義が含まれていると発生する場合があります。Oracle Rdbでは、レコード定義にあるフィールド定義のみ許容されます。- %CDD-E-INVALID_RDB_DIM, record PARTS has dimension and cannot be used by Oracle Rdb
このエラーは、リポジトリのレコード定義にARRAY句が含まれていると発生する場合があります。
- CREATE TABLE文は、作成者にデータベースに対するすべての権限を付与し、他のすべてのユーザーには権限を付与しないという、表のデフォルト・アクセス権限セットを作成します。つまり、新しい表にはNONEのPUBLICアクセスが付与されています。
新たに作成された表のデフォルトのPUBLICアクセスをオーバーライドするには、システム権限表にDEFAULTの名前で識別子を定義します。データベースについてこの識別子に付与するアクセス権は、作成した新しい表に割り当てられます。
- 別名TEST1のデータベースへのSELECT権限およびUPDATE権限の割当て
SQL> ATTACH 'ALIAS test1 FILENAME mf_personnel'; SQL> SHOW PROTECTION ON DATABASE test1; Protection on Alias TEST1 (IDENTIFIER=[DBS,SMALLWOOD],ACCESS=SELECT+INSERT+UPDATE+DELETE+ SHOW+CREATE+ALTER+DROP+DBCTRL+OPERATOR+DBADM+SECURITY+DISTRIBTRAN) (IDENTIFIER=[*,*],ACCESS=NONE) SQL> GRANT SELECT, UPDATE ON DATABASE ALIAS TEST1 cont> TO DEFAULT;
- 保護を変更するためのトランザクションのコミットおよび切断
SQL> COMMIT; SQL> DISCONNECT ALL;
- 新しい表TABLE1へのすべてのアクセス権の受領
データベースの既存の表に対する保護は変更されません。ただし、定義する新しい表はDEFAULT識別子で指定された保護を受けます。この例では、所有者(SMALLWOOD)は、新しい表TABLE1に対するすべてのアクセス権を受け取り、その他のユーザーはDEFAULT識別子で指定されたSELECTアクセス権およびUPDATEアクセス権を受け取ります。
SQL> ATTACH 'ALIAS test1 FILENAME mf_personnel'; SQL> SET TRANSACTION READ WRITE; SQL> CREATE TABLE test1.table1 cont> (last_name_dom CHAR(5), cont> year_dom SMALLINT); SQL> SHOW PROTECTION ON test1.table1; Protection on Table TEST1.TABLE1 (IDENTIFIER=[DBS,SMALLWOOD],ACCESS=SELECT+INSERT+UPDATE+DELETE+ SHOW+CREATE+ALTER+DROP+DBCTRL+REFERENCES) (IDENTIFIER=[*,*],ACCESS=SELECT+UPDATE)
DEFAULT識別子は通常、OpenVMSシステム上にあります。ただし、DEFAULT識別子がシステムから削除されると、Oracle Rdbによってエラー・メッセージが返されます。
SQL> GRANT INSERT ON DATABASE ALIAS TEST1 to DEFAULT; %SYSTEM-F-NOSUCHID, unknown rights identifier
- 列のデフォルト値として使用する値がある場合は、どのような値であるかを考慮する必要があります。NULLやNot Applicableなどの値を使用し、列へのデータ挿入が行われないことを明確に示すことができます。通常、列に特定の値が含まれる場合は、その値をデフォルトとして使用できます。たとえば、従業員のほとんどがフル・タイムで稼働する場合は、フル・タイムをwork status列のデフォルト値にできます。
- ドメインに基づく列にデフォルト値を指定する際に、そのドメインに対してもデフォルト値を指定している場合は、列に対するデフォルト値でドメインに対するデフォルト値がオーバーライドされます。
- 表レベルまたは列レベル、あるいはその両方で表固有の制約を宣言できます。このような制約では、列には特定の値、主キー値、一意の値のみを格納できるよう指定するか、値を欠落(NULL)にできないよう指定できます。表レベルおよび列レベルの両方で、複数の制約を宣言できます。
両方のレベルで、一意キー、主キー、および一意キーまたは主キーを参照する外部キーの定義を指定できます。制約の評価時間も指定できます(コミットまたは更新)。
表レベルでは、複数列のキーの制約を定義できます。
列レベルでは、列の値をNULLでない値に制限できます。- SET ALL CONSTRAINTS文を使用して、データベース・システムが制約を評価するタイミングを制御できます。
- 制約をNOT DEFERRABLEとして定義した場合、INSERT文、DELETE文またはUPDATE文の実行時に制約を評価する必要があります。評価時間の変更には、SET ALL CONSTRAINTS文やSET TRANSACTION EVALUATING文は使用できません。
- 制約は、表に格納できる値を制限する条件を指定します。条件に違反するINSERT文、UPDATE文、DELETE文はいずれも失敗します。データベース・システムによってRDB$_INTEG_FAILエラーが生成され、SQLによってSQLCODE値--1001が返されます。
DECLARE文およびSET TRANSACTION文のEVALUATING句により、データベース・システムによる制約の評価タイミングを制御できます。デフォルトでは、トランザクションがCOMMIT文を発行すると、すべての遅延制約が評価されます。ただし、DECLARE文またはSET TRANSACTION文のEVALUATING句で特定の制約に対してVERB TIMEを指定すると、データベース・システムではUPDATE文、INSERT文またはDELETE文の実行時に常にこれらの制約が評価されます。
SQLでは、列の制約と表の制約が可能です。2つのタイプの制約のセマンティクスと構文は類似していますが同じではありません。次にその相違点を示します。
- 列の制約ではUNIQUE引数を使用でき、表の制約ではUNIQUE (column-name)引数を使用できます。一連の列定義に対するUNIQUEの指定は、UNIQUEと同一列のリストの指定より制限的です。これは、SQLでは、UNIQUE (column-name)表制約の列の組合せが一意であることのみ必要とされるためです。
SQL> CREATE TABLE TEMP1 cont> ( COL1 REAL NOT NULL UNIQUE CONSTRAINT C1, cont> COL2 REAL NOT NULL UNIQUE CONSTRAINT C2, cont> COL3 REAL NOT NULL UNIQUE CONSTRAINT C3 ); SQL> SQL> CREATE TABLE TEMP2 cont> ( COL4 REAL NOT NULL CONSTRAINT C4, cont> COL5 REAL NOT NULL CONSTRAINT C5, cont> COL6 REAL NOT NULL CONSTRAINT C6, cont> UNIQUE (COL4, COL5, COL6) CONSTRAINT C7 ); SQL> SQL> INSERT INTO TEMP1 VALUES (1,1,1); 1 row inserted SQL> INSERT INTO TEMP2 VALUES (1,1,1); 1 row inserted SQL> COMMIT; SQL> SQL> -- This fails because the values SQL> -- in COL1 will not be unique: SQL> INSERT INTO TEMP1 VALUES (1,2,2); 1 row inserted SQL> COMMIT; %RDB-E-INTEG_FAIL, violation of constraint C1 caused operation to fail SQL> SQL> ROLLBACK; SQL> SQL> -- This succeeds because the *combination* SQL> -- of the columns is still unique: SQL> INSERT INTO TEMP2 VALUES (1,2,2); 1 row inserted SQL> COMMIT;
- CHECK制約では、列制約の構文が表制約の構文と同じです。2つのCHECK制約間の構文では、CHECK表制約はカンマによって列定義と区別され、CHECK列制約は区別されないという点のみが異なります。
CHECK列制約の条件では、関連付けられた列のみ直接参照します。CHECK表制約の条件は、表の任意の列を直接参照できます。ただし、どちらのタイプのCHECK制約も、条件の列選択式を介してデータベースの他の表の列を参照できます。
CHECK制約の条件はFALSEにはできません。不明にすることはできます。制約COL 10 > 100では、値101、1000およびNULLを使用できます。値99は使用できません。
SQL> -- Cannot directly refer to TEST1 in SQL> -- column constraint for TEST2: SQL> CREATE TABLE TEST cont> ( TEST1 CHAR(5), cont> TEST2 CHAR(5) cont> CHECK (TEST2 <> TEST1) cont> ); %SQL-F-COLNOTVAL, The column CHECK constraint cannot refer to the column TEST1 SQL> -- To get around the problem, make the CHECK constraint a table SQL> -- constraint by separating it from the column with a comma: SQL> CREATE TABLE TEST cont> ( TEST1 CHAR(5), cont> TEST2 CHAR(5), cont> CHECK (TEST2 <> TEST1) cont> ); SQL> COMMIT; SQL> INSERT INTO TEST VALUES ('1','1'); 1 row inserted SQL> COMMIT; %RDB-E-INTEG_FAIL, violation of constraint TEST_CHECK1 caused operation to fail SQL> ROLLBACK; SQL> -- This table shows that a CHECK column constraint SQL> -- can refer to other tables in column select expressions: SQL> CREATE TABLE TEST0 cont> ( TEST1 CHAR(5), cont> TEST2 CHAR(5) cont> CHECK (TEST2 NOT IN cont> (SELECT TEST1 FROM TEST0) ) cont> );
- 一意の列または表制約の指定の代替方法としては、UNIQUEキーワードを指定してCREATE INDEX文を使用できます。通常、UNIQUE索引を指定すると、表定義に論理的に等しい制約を指定するよりパフォーマンスが向上します。
- REFERENCES句では、一意キーまたは主キーを構成する被参照表の対応する列を1つ以上宣言できます。宣言しない場合、被参照表には、対応する列を指定する表レベルでPRIMARY KEY制約を組み込む必要があります。
- 言語がSQL99またはORACLE LEVEL2の場合、REFERENCES句の列のリストは、対応するPRIMARY KEY制約やUNIQUE制約の順序と一致する必要はありません。その他の言語では一致する必要があります。
- 外部キー内の値は、関連する一意キーまたは主キーの値と一致する必要があります。SQLでは、次のいずれかの文が該当する場合、外部キーは関連する一意キーまたは主キーに一致するとみなされます。
- 外部キーの列にNULL値が含まれる場合。この場合、外部キーはNULLです。SQLでは、NULLの外部キーは関連する一意キーまたは主キーに一致するとみなされます。
- 外部キーのいずれの列にもNULL値が含まれず、外部キーの値セットが一意キーまたは主キー内にも存在する場合。つまり、参照表のすべての行で、対応する列が等しい被参照表に行が1つある場合、外部キーは関連する一意キーまたは主キーに一致します。
次の例は、最初の一致タイプを示しています。表FOREIGNの列B2に格納されているNULL値により、B1およびB2の外部キーがNULL外部キーになります。B1およびB2は、NULL外部キーとして表PRIMARYの主キーA1およびA2に一致します。
SQL> CREATE TABLE PRIMARY_TAB cont> ( A1 INTEGER, cont> A2 INTEGER, cont> PRIMARY KEY (A1, A2), cont> A3 INTEGER); SQL> SQL> INSERT INTO PRIMARY_TAB (A1, A2, A3) cont> VALUES (1, 1, 1); 1 row inserted SQL> SQL> CREATE TABLE FOREIGN_TAB cont> ( B1 INTEGER, cont> B2 INTEGER, cont> FOREIGN KEY (B1, B2) cont> REFERENCES PRIMARY_TAB (A1, A2), cont> B3 CHAR(5)); SQL> -- The following command stores a null value in column B2: SQL> INSERT INTO FOREIGN_TAB (B1, B3) VALUES (2, 'AAAAA'); 1 row inserted
次の例は、2つ目の一致タイプを示しています。表FOREIGN_2の列D1およびD2(外部キー)に格納されている値は、表PRIMARY_2の列C1およびC2(主キー)に格納されている値に完全に一致します。
SQL> CREATE TABLE PRIMARY_2 cont> (C1 INTEGER, cont> C2 INTEGER, cont> PRIMARY KEY (C1, C2), cont> C3 INTEGER); SQL> SQL> INSERT INTO PRIMARY_2 (C1, C2, C3) cont> VALUES (5, 3, 2); 1 row inserted SQL> SQL> CREATE TABLE FOREIGN_2 cont> ( D1 INTEGER, cont> D2 INTEGER, cont> FOREIGN KEY (D1, D2) cont> REFERENCES PRIMARY_2 (C1, C2), cont> D3 CHAR(5)); SQL> -- SQL> INSERT INTO FOREIGN_2 (D1, D2, D3) VALUES (5, 3, 'BBBBB'); 1 row inserted
- 表固有の制約は、次のように使用できます。
- 明確で、具体的な規則セットの作成による参照整合性の維持
- 目的の整合性規則の表定義への直接アタッチ
- 同一タスク達成のための、複数の外観上独立した制約の定義の回避
- 制約では、セグメント化された文字列として定義した列は指定できません。これは、セグメント化された文字列IDのみが参照され、実際のセグメント化された文字列は参照されないためです。
- 表定義内では、制約は表の特定行、表の内容全体、または複数の表の状態に対して適用できます。
- 表定義内では、Oracle Rdbが最初に列の新バージョンを定義します。次にSQLが列を定義して評価します。したがって、列と制約が同じ表定義内で定義される場合、制約はこの表に定義された、制約定義テキストの前後のどの列でも使用できます。
- CREATE TABLE文で表固有の制約が宣言され、生成された制約の定義が失敗した場合、表の定義も失敗します。
- CREATE TABLE文により、表定義と関連する制約定義が物理データベースに追加されます。
PATHNAME引数でデータベースがアタッチされている場合、定義はリポジトリに格納されるため、データベース定義とリポジトリ定義の整合性が保持されます。- 冗長な表固有の制約定義を回避するには、SHOW TABLE文を使用して対象となる表の制約とトリガーをすべて表示させます。
- コミット時に制約が失敗した場合は、更新操作は手動でロールバックする必要があります。
- 最大で8191の表を作成できます。この値はディスク上の構造によって制限されたアーキテクチャの限界であり、システム表も含まれます。上限を超えた場合、Oracle Rdbによってエラー・メッセージが返されます。
古い表を削除すると、Oracle Rdbではその識別子が再利用され、上限に達した後もCREATE TABLE文が正常に終了します。- プログラムにおけるCREATE TABLE文は、表を参照する他のデータ定義言語(DDL)文より(ソース・ファイルにおいて)優先される必要があります。
- NCHAR、NATIONAL CHAR、NCHAR VARYINGまたはNATIONAL CHAR VARYINGデータ型を使用すると、各国語キャラクタ・データ型を指定できます。各国語キャラクタ・データ型は、データベースの作成時に、データベース各国語キャラクタ・セットによって定義されます。各国語キャラクタ・データ型の詳細は、第2.3節を参照してください。
- データ型の長さは、文字またはオクテットで指定できます。デフォルトでは、データ型はオクテットで指定されます。CREATE TABLEコマンドをSET CHARACTER LENGTH文またはSET DIALECT文とともに前に配置すると、長さを文字数に変更できます。詳細は、それぞれ「SET CHARACTER LENGTH文」および「SET DIALECT文」を参照してください。
- 一時表のデータはセッションに対しては非公開のため、永続実表での使用と同じように多数の場所で一時表を使用することはできません。一時表を使用する場合、特に次の点に注意してください。
- TRUNCATE TABLE文を使用すると、グローバル一時表を切り捨てられます。ローカル一時表は切り捨てられません。
- グローバル一時表およびローカル一時表では、データ型LIST OF BYTE VARYINGのデータは含められません。
- グローバル一時表には列制約および表制約を定義できますが、ローカル一時表には定義できません。グローバル一時表とローカル一時表の列は、どちらもドメイン制約を参照できます。
グローバル一時表に対する制約では、別のグローバル一時表のみを参照できます。ただし、被参照ターゲット表でON COMMIT DELETE ROWSを指定している場合は、ソース表でもON COMMIT DELETE ROWSを指定する必要があります。この制限は、被参照ターゲット表でON COMMIT PRESERVE ROWSを指定する場合は適用されません。- トリガーはグローバル一時表でのみ使用できます。
- グローバル一時表またはローカル一時表には、索引は定義できません。
- Oracle Rdbでは、グローバル一時表またはローカル一時表への変更はジャーナリングしません。
- グローバル一時表またはローカル一時表では、次のことが可能です。
- DROP TABLE文を使用して一時表を削除します。
- ビューで一時表を参照します。
- 一時表でdbkeyを使用します。
- ALLキーワードのみを使用して権限を付与および取り消します。
- 読取り専用トランザクション中に一時表への書込みを行います。
- 表6-5に、一時表を参照できる場合に可能なアクションの概要を示します。
表6-5 一時表の使用 一時表の種類 アクション グローバル ローカル 宣言されたローカル 表の削除 ○ ○ × 表の変更 ○ × × 表の切捨て ○ × × 表または列に対する制約の追加 ○ × × 制約定義の表の参照 ○2 ○ × ドメイン制約の参照 ○ ○ ○ 記憶域マップの表の参照 ○3 ○ × ビューの表の参照 ○ ○ × 一時表に対する権限の付与 ○ ○ × アウトラインの表の参照 ○ ○ ×1 表での索引の作成 × × × 表でのdbkeyの使用 ○ ○ ○ 表でのトリガーの使用 ○ × × COMMENT ON文での表の参照 ○ ○ × LIST OF BYTE VARYINGデータの格納 × × × RESERVING句での指定 ○4 ○4 × 読取り専用トランザクション中の表への書込み ○ ○ ○ 読取り専用トランザクションでの作成 × × ○ COMPUTED BY列での表の参照 ○ ○ ×