* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Download Referential Integrity in Oracle Rdb
Survey
Document related concepts
Concurrency control wikipedia , lookup
Entity–attribute–value model wikipedia , lookup
Oracle Database wikipedia , lookup
Microsoft Jet Database Engine wikipedia , lookup
Relational algebra wikipedia , lookup
Clusterpoint wikipedia , lookup
Extensible Storage Engine wikipedia , lookup
Open Database Connectivity wikipedia , lookup
Microsoft SQL Server wikipedia , lookup
Database model wikipedia , lookup
Transcript
Referential Integrity in Oracle Rdb Oracle Rdb has fully supported constraint definition and execution since its first version which was released in 1984. At that time there was no SQL standard, nor did Rdb use the SQL nomenclature for this feature. Rdb implemented three types of constraints - valid if, verb time and commit time. Traces of this terminology exist still in the Rdb product, even in the SQL syntax. This technical note provides an overview of the referential integrity features available in the Oracle Rdb product. It is written from an historical perspective examining changes in this feature since the first versions of Rdb and relates the Rdb and SQL standard features and terminology. ANSI and ISO SQL-92 define constraints in various classes: PRIMARY KEY, FOREIGN KEY, NOT NULL, UNIQUE and CHECK constraints. CHECK is the most general and can be used to define similar constraints to the other special cases. However, the added semantics of PRIMARY KEY, etc. can be used by the underlying engine to optimize the query. For instance a uniqueness constraint such as UNIQUE need only be evaluated during INSERT on the table, it need not be evaluated on DELETE from a referenced table as would be required for a FOREIGN KEY. When a constraint is defined it is immediately validated against existing inserted data to ensure that no existing data violates the new referential integrity rules. In the case of domain constraints, the CHECK constraint will be applied to each table and column which references the domain and it will be validated against existing data in those tables. Rdb implements all the constraint types by means of stored BLR queries in the database. BLR is the internal format for a query and can be displayed by using the RDMS$DEBUG_FLAGS "M" (or SET FLAGS 'MBLR' in Rdb7 and later versions) during table creation. Alternatively, RMU/EXTRACT/OPTION=DEBUG can be used to have the stored BLR for most the constraints dumped during table extraction. Table 1 Constraint Types Type Internal name Comment Domain Constraints Valid If Can only reference the domain, and therefore can not contain subqueries Not Deferrable Verb Time Constraint Arbitrary query complexity e.g. subqueries, external routine calls, etc. These constraints can not be deferred using the EVALUATING clause of SET TRANSACTION Deferrable Immediate Verb Time Constraint Arbitrary query complexity. e.g. subqueries, external routine calls, etc. These constraints may be deferred using the EVALUATING clause of SET TRANSACTION Deferrable Commit Time Constraint Arbitrary query complexity. e.g. subqueries, external routine calls, etc. 1 Domain Constraints This type of constraint was originally implemented for the VALID IF clause of the RDO language interface to Rdb. Oracle CDD/Repository also supports the definition of VALID IF constraints in the CDO interface. The SQL language interface uses VALID IF to implement domain CHECK constraints. It should be noted that the BLR generated for this type of constraint by SQL is more complex, slightly different in semantics than what is generated by the RDO or CDO interfaces. Domain constraints in Rdb are always NOT DEFERRABLE. Rdb compiles the constraint (or validation) into the query itself. This makes these types of constraints the most efficient. As the definition is based on the domain it is limited in what it can check, but is excellent for range checks, and NOT NULL constraints. 2 VERB TIME versus COMMIT TIME This internal notation is used to define the evaluation times of a constraint. Some SQL statements require multiple verbs to implement. However, in general a VERB can be considered to be the same as a SQL statement. As each table is referenced by a query its constraints are compiled and stored in the user process context. If the query doesn't modify columns referenced by the constraint, or modifies them to the same values as existed before the evaluation, then the constraint evaluation is bypassed for that row. Each constraint is a separate query and they are separately optimized and executed. Therefore, they can be tuned using query outlines by creating an outline with the same name as the constraint. In some cases the query generated for the constraint is reworked by the optimizer to a form which is more easily optimized. For instance, it might be changed to perform direct DBKEY lookup rather than perform a table or index scan. Other optimizations are also performed for FOREIGN KEY, UNIQUE and PRIMARY KEY constraints. If CHECK constraints conform to some known patterns then these will also be reworked by the optimizer. A user can define a table, or column constraint and specify if it as DEFERRABLE or NOT DEFERRABLE which indicates when the constraint is to be executed. A NOT DEFERRABLE constraint is executed as part of the SQL statement and is often executed more efficiently (e.g. NOT NULL). In general NOT DEFERRABLE constraints should be used when integrity is maintained by a single statement. If multiple statements are required to maintain integrity, with intermediate results that would violate some constraints, then DEFERRABLE constraints need to be used. If you use the SQL dialect 'SQL92' (and I recommend that this be used) then Rdb will manage some NOT DEFERRABLE constraints differently. This is explained below (see Section 4). A DEFERRABLE constraint can be executed immediately after the statement up to commit time. By default it will execute at commit time. The user can use the SET ALL CONSTRAINT statement to define the timing (IMMEDIATE, or DEFERRED) as well as force constraint evaluation when SET CONSTRAINT is used. If SET ALL CONSTRAINT IMMEDIATE is used then all subsequent statements will be followed by the evaluation of all active DEFERRABLE constraints. Once evaluated they will not be re-executed unless reactivated by a query. The mode in this case is reset by the start of the next transaction. SQL also contains a SET DEFAULT CONSTRAINT MODE statement so that the evaluating time is established for the entire session. In Oracle Rdb8 the constraint evaluation time syntax from SQL-92 was completed to allow some refinement of the constraint definition. The syntax is actually quite involved but there are only really three options available: 1. NOT DEFERRABLE INITIALLY IMMEDIATE This is the same as NOT DEFERRABLE from previous versions. 2. DEFERRABLE INITIALLY DEFERRED This is the same as DEFERRABLE from previous versions. 3. DEFERRABLE INITIALLY IMMEDIATE This is a new option for SQL and corresponds to the VERB TIME constraints of RDO. The database administrator can also force evaluation of all constraints using the /CONSTRAINT qualifier with the RMU/VERIFY command. This is a useful tool for checking the referential integrity of the entire database. Note that domain constraints are not currently evaluated by RMU/VERIFY. In Rdb7 an option was added to RMU/VERIFY to verify only constraints which referenced a particular table, or possibly just a particular constraint. In addition RMU/VERIFY now attempts to validate as many constraints as possible and report those failing constraints. In prior versions RMU/VERIFY would abort constraint verification when the first failed. Rdb also supports an EVALUATING clause on the SET TRANSACTION statement. This statement can be used to convert a VERB TIME constraint to a COMMIT TIME constraint (or vice versa) at the transaction startup. For example, set transaction read write evaluating JOBS_CHECK at verb time, EMPS_CHECK at commit time; A NOT DEFERRABLE constraint can never have its evaluation time changed. However, in Rdb8 the DEFERRABLE INITIALLY IMMEDIATE constraint can be affected by the EVALUATING clause. 3 How it all works? As each user query, stored procedure or trigger is compiled any constraints which are affected by INSERT, UPDATE and DELETE statements are loaded. Different statements will cause different constraint to be loaded. For example, an UPDATE will cause a UNIQUE constraint to be loaded because it updates a constrained column but a DELETE does not need to load the constraint because uniqueness is no affected by removing a row. When the statement is executed all the NOT DEFERRABLE constraints are evaluated and all DEFERRABLE constraints are placed on a list for later processing. The constraints on this deferred list will be evaluated at COMMIT time, unless the user initiates a SET ALL CONSTRAINT IMMEDIATE statement. In the latter case the constraints are evaluated immediately. They are not re-evaluated unless replaced on the COMMIT list by another query. For the remainder of the transaction deferred constraints are executed immediately after a statement executes. There is a subtle timing difference between these DEFERRED IMMEDIATE constraint evaluations and NOT DEFERRED constraints. A deferred constraint is evaluated when the API routine rdb_check_constraints is called (on your behalf by SQL), or when a COMMIT is executed. A not deferred (or verb time) constraint is evaluated during execution of the query. 4 Changes for SQL-92 Compliance By default NOT DEFERRABLE is executed row by row which may produced anomalies such as shown in the following example: SQL> create table t (c integer unique not deferrable); SQL> insert into t value (1); 1 row inserted SQL> insert into t value (1); -- expected error %RDB-E-INTEG_FAIL, violation of constraint T_UNIQUE_C caused operation to fail -RDB-F-ON_DB, on database DISK1:[JONES.DATABASES]MF_PERSONNEL.RDB;1 SQL> insert into t value (2); 1 row inserted SQL> update t set c = c + 1; -- (1) %RDB-E-INTEG_FAIL, violation of constraint T_UNIQUE_C caused operation to fail -RDB-F-ON_DB, on database DISK1:[JONES.DATABASES]MF_PERSONNEL.RDB;1 This update statement ( (1) ) should have succeeded since its compound effect is to update all the rows and so maintain the uniqueness of the columns. However, the constraint is evaluated a row at a time and for a short time there exists duplicate values which causes the failure and abort of the statement. Rdb was changed in V6.0 to conform to the SQL-92 standard. If any constraint evaluation fails in a multi-row statement (such as a searched UPDATE) then it is deferred until the end of the UPDATE statement. This scheme has the advantage of the row at a time evaluation (the most efficient since the row is already in memory) with a fall back to a per statement evaluation if failures occur. This same script when run using dialect 'SQL92' results in expected behavior. SQL> set dialect 'SQL92'; SQL> attach 'filename MF_PERSONNEL'; SQL> create table t (c integer unique not deferrable); SQL> insert into t value (1); 1 row inserted SQL> insert into t value (1); -- expected error %RDB-E-INTEG_FAIL, violation of constraint T_UNIQUE_C caused operation to fail -RDB-F-ON_DB, on database DISK1:[JONES.DATABASES]MF_PERSONNEL.RDB;1 SQL> insert into t value (2); 1 row inserted SQL> update t set c = c + 1; 2 rows updated SQL> 5 Can constraints be disabled? As stated previously a constraint is an extra query to be performed during database updates. It is often desirable to eliminate this overhead when the data is loaded in bulk or has already been validated. Prior to Oracle Rdb7 a constraint could only be disabled by using the ALTER TABLE ... DROP CONSTRAINT statement. When the constraint is later redefined using ALTER TABLE ... ADD CONSTRAINT the table must be scanned and the data re-validated. Adding back the dropped constraint can be a time consuming task. In Oracle Rdb7, RMU/LOAD supports a /NOCONSTRAINTS qualifier that allows inserts with constraint evaluation disabled. This functionality is further enhanced in Oracle Rdb8 which provides syntax in CREATE and ALTER TABLE which specifies that one or more constraints be disabled. SQL> alter table EMPLOYEES cont> disable all constraints; SQL> show table (constraint) EMPLOYEES Table constraints for EMPLOYEES: EMPLOYEES_PRIMARY_EMPLOYEE_ID Primary Key constraint Column constraint for EMPLOYEES.EMPLOYEE_ID Evaluated on COMMIT Source: EMPLOYEES.EMPLOYEE_ID PRIMARY KEY Constraint is disabled . . . When the constraint is enabled the table is scanned to ensure database integrity. The ENABLE NOVALIDATE option allows a knowledgeable database administrator to avoid the time and I/O resources required to re-validate data when the data is already valid. In this case the table is not scanned and Rdb assumes table data correctness. You must be a privilege user to use the NOVALIDATE clause. Use the SHOW TABLE command to see if the constraint is in a "not validated" state. SQL> alter table EMPLOYEES cont> enable novalidate all constraints; SQL> show table (constraint) EMPLOYEES Table constraints for EMPLOYEES: EMPLOYEES_PRIMARY_EMPLOYEE_ID Primary Key constraint Column constraint for EMPLOYEES.EMPLOYEE_ID Evaluated on COMMIT Source: EMPLOYEES.EMPLOYEE_ID PRIMARY KEY Constraint is not validated . . . Although constraint are disabled, they can still be explicitly evaluated using the RMU/VERIFY command. RMU ignores the disabled state when the constraint is explicitly named with the /CONSTRAINT qualifier. This allows important business rules to be added to the database and verified periodically. For instance, some complex business rules are enforced by the user applications and doubly checking them with constraints might be an unacceptable overhead. Now they can be defined in the database, kept disabled and verified by the database administrator at convenient times. Appendix A Some History of Constraint Evaluation in Rdb Several interesting sections have been extracted from the Rdb release notes. The product names have been left as originally publish. A.1 From the Rdb V2.1/V2.2 Release Notes A.1.1 Constraint Optimizations Several types of constraint evaluation operations have been optimized in V2.1: Existence Uniqueness Modification Database key (dbkey) retrieval and erasing Multiple evaluations The following sections describe the nature of these optimizations. A.1.1.1 Existence Constraint The existence constraint, which is implemented by using the "REQUIRE <conditional-expr>" option of the DEFINE CONSTRAINT statement, is not evaluated when you store records in or erase records from relations named in the constraint. For example: DEFINE CONSTRAINT EMP_EXISTS FOR SH IN SALARY_HISTORY REQUIRE ANY E IN EMPLOYEES WITH E.EMPLOYEE_ID = SH.EMPLOYEE_ID. Rdb/VMS need not evaluate this constraint when you store records in EMPLOYEES relation or erase records from the SALARY_HISTORY relation. If the query includes a "NOT ANY" clause, Rdb/VMS does not require constraint evaluation when you erase records from either relation. A.1.1.2 Uniqueness Constraint The uniqueness constraint is not evaluated when a record in a relation named in the constraint is erased from the database. See the following example. DEFINE CONSTRAINT EMP_UNIQUE FOR E IN EMPLOYEES REQUIRE UNIQUE E1 IN EMPLOYEES WITH E1.EMPLOYEE_ID = E.EMPLOYEE_ID. This constraint does not have to be evaluated when you erase records from the EMPLOYEES relation. A.1.1.3 Modification Operation If the fields in the relation you modify are not named in the constraint definition, Rdb/VMS need not evaluate the constraint. For example: DEFINE CONSTRAINT EMP_ID_RANGE FOR E IN EMPLOYEES REQUIRE REQUIRE E.EMPLOYEE_ID > "00000". If you modify fields other than EMPLOYEE_ID in the EMPLOYEES relation, Rdb/VMS does not have to evaluate this constraint. If any field named in the constraint is a COMPUTED BY field, the constraint always is evaluated whenever you modify any field in the relation. If the modification is an equivalence statement, the constraint does not have to be evaluated. For example, Rdb/VMS does not evaluate the constraint when the following query executes: FOR E IN EMPLOYEES MODIFY E USING E.EMPLOYEE_ID = E.EMPLOYEE_ID END_FOR A.1.1.4 Database Key Retrieval and Erasing Consider the following constraint definition: DEFINE CONSTRAINT EMP_EXIST_SH FOR E IN EMPLOYEES REQUIRE ANY SH IN SALARY_HISTORY WITH SH.EMPLOYEE_ID = E.EMPLOYEE_ID. Rdb/VMS uses database keys to locate records in the database for retrieval. In this example, any query executed for the EMPLOYEES relation processes records in that relation one record at a time. Because Rdb/VMS already has dbkeys for each record it processes, the constraint evaluation mechanism can use these database keys to retrieve single records for constraint evaluation. Previous versions of Rdb/VMS might have processed such a constraint definition for all records in the relation named in the RSE of the FOR clause in the constraint definition. The relations in the RSE of the FOR component in the constraint definition never violate the constraint when you erase records from them. Therefore, the constraint will not be evaluated. A.1.1.5 Multiple Evaluations Multiple evaluations of a constraint definition do not occur for relations mentioned more than once. For example: DEFINE CONSTRAINT EMP_UNIQUE FOR E IN EMPLOYEES REQUIRE UNIQUE E1 IN EMPLOYEES WITH E1.EMPLOYEE_ID = E.EMPLOYEE_ID. Although this constraint definition specifies the EMPLOYEES relation twice, Rdb/VMS does not need to evaluate this constraint more than once for this relation. In fact, if the relation is named in the RSE of the constraint definition FOR statement, Rdb/VMS uses the dbkey retrieval strategy described in the previous section. A.2 From the Rdb V4.0 Release Notes A.2.1 Constraint Evaluation The following improvements have been made to constraint evaluation: Constraint evaluation on a MODIFY or UPDATE clause Rdb/VMS evaluates constraints on a MODIFY or UPDATE clause only when the column values change. Rdb/VMS no longer evaluates constraints if the columns referenced by the constraints have not actually been modified. Constraints consume less compilation and execution resources Constraint compilation for any given update request now takes up to 50% less time, and the resultant constraint execution structures take up to 50% less virtual memory. In addition, the number of constraints queued for deferred execution (CHECK ON COMMIT) is frequently less, by a factor of the number of rows updated per the request. FOREIGN KEY constraints optimized for verb time evaluation Updates and deletions to PRIMARY KEY values referenced by FOREIGN KEY constraints no longer cause a full scan of the PRIMARY KEY table when the FOREIGN KEY constraint is executed at verb time. Such constraints are optimized to compare the FOREIGN KEY column values against only the old values of the PRIMARY KEY columns. This optimization is not available for constraints whose evaluation is deferred until SQL statement end or COMMIT. A.2.2 Cautions on Using ANY, ALL, or IN Clauses in Constraint Definitions For Rdb V3.1, a change was made to correct the results returned by the ANY (SOME) and ALL predicates to conform to the ANSI/ISO SQL standard. The changes required for ANSI compliance produced a different type of query for ANY and ALL (and for the IN predicate when a query expression is used) such that the query can no longer be selectively evaluated when used in a constraint. The workaround for any performance problems introduced by this change is re-creating the affected constraint with an EXISTS predicate (or equivalent) applied to a column select expression, as shown in the following example: CHECK (T1.F1 IN (SELECT T2.F1 FROM T2)) - to CHECK (EXISTS (SELECT * FROM T2 WHERE T2.F1 = T1.F1)) - or CHECK ((SELECT COUNT (*) FROM T2 WHERE T2.F1 = T1.F1) <> 0) A.3 From the Rdb V6.0 Release Notes A.3.1 Constraint BLR May Not Reflect Actual Execution Strategy When :DEC Rdb compiles a primary or foreign key constraint query, the constraint handling code in :DEC Rdb in most cases reformats the query structure to enable the optimizer to generate the most efficient strategy for constraint evaluation. The reformatting of a constraint query is internal to :DEC Rdb and therefore is not visible to the user or to other layered software products, such as :DEC RdbExpert. As a result of internal reformatting of a constraint query the actual execution strategy used to evaluate the constraint may be much different from what it would have been if no internal reformatting was done. The constraint binary language representation (BLR) simply shows the standard format of a primary or foreign key constraint query. It does not reflect any internal reformatting performed by :DEC Rdb. Therefore, you cannot draw conclusions from a constraint BLR about the execution strategy used by :DEC Rdb to evaluate the constraint. A.3.2 New RDMS$DEBUG_FLAGS Logical Name Flag Combinations Show Query Outlines For :DEC Rdb for OpenVMS VAX V6.0, defining the RDMS$DEBUG_ FLAGS logical name with the following flag combinations enables display of query outline definitions: "Ss" flags-display query outline definitions for all nonsystem queries. "ISs" flags-display query outline definitions for system-created queries such as those generated when :DEC Rdb compiles constraint and trigger internal queries. "ISsn" flags-display the names of the constraints or triggers (or both) for which query outlines are generated. For example, the following command combines the "I" (Internals) flag with the "Ss" (Dump query outlines) flags: $ DEFINE RDMS$DEBUG_FLAGS "ISs" The following command adds the "n" (Show names) flag to the flags in the preceding example: $ DEFINE RDMS$DEBUG_FLAGS "ISsn" Note that the "s" and "n" flags must be lowercase and must follow immediately after the uppercase "S" (Strategy) flag. A.4 From the V6.1 Release Notes A.4.1 Named Query Outlines May Now Be Used by Triggers and Constraints During compilation of a constraint or trigger, Rdb will now search for a query outline with the same name as the trigger or constraint being compiled. If a match is found, that outline will be used during the query compilation of the trigger or constraint. If no outline is found matching the name of the object, Rdb will then try to locate an appropriate outline using the BLR ID of the query. For example: SQL> create table TAB1 (a1 int constraint TAB1NOTNULL not null, cont> a2 char(10), cont> a3 char(10) ); SQL> create outline TAB1NOTNULL cont> id '8755644BCB040948E28A76B6D77CC2D3' cont> mode 0 cont> as ( cont> query ( cont> subquery ( cont> TAB1 0 access path sequential cont> ) cont> ) cont> ) cont> compliance optional ; SQL> create trigger TAB1TRIG before insert on TAB1 cont> (update TAB1 set a3= 'bbbb' where a2 = 'aaaa') for each row; SQL> create outline TAB1TRIG cont> id '990F90B45658D27D64233D88D16AD273' cont> mode 0 cont> as ( cont> query ( cont> subquery ( cont> TAB1 0 access path sequential cont> ) cont> ) cont> ) cont> compliance optional ; . . . $ DEFINE RDMS$DEBUG_FLAGS "SnsI" . . . SQL> insert into tab1 (a1) value (11); ~S: Trigger name TAB1TRIG ~S: Outline TAB1TRIG used ~S: Outline TAB1NOTNULL used Conjunct Get Retrieval sequentially of relation TAB1 . . . 1 row inserted SQL> commit; ~S: Constraint TAB1NOTNULL evaluated Conjunct Get Retrieval sequentially of relation TAB1 A.5 From the Rdb7 Release Notes A.5.1 SQL92 Intermediate Level UNIQUE Constraint available in Rdb7 Oracle Rdb now provides an SQL92 intermediate level compliant UNIQUE constraint. This type of constraint excludes columns which are NULL from the UNIQUE comparison. This effectively allows sets of columns to be UNIQUE or NULL. This type of constraint will be created by default when the SQL dialect is set to 'SQL89', 'MIA', 'ORACLE LEVEL1' or 'SQL92'. The default dialect is SQLV40. Oracle recommends that you set the dialect to SQL92 (or one of the listed dialects) before using CREATE or ALTER TABLE to add UNIQUE constraints to tables. Note The new UNIQUE semantics will be used at run-time under any selected dialect. i.e. the table must be created or altered under the listed dialects to have the new style of unique enabled. Improved Performance The new UNIQUE constraint implementation, in addition to conforming to the Database Language SQL standard (SQL92 Intermediate Level) also provides improved performance for single row inserts. This is made possible by eliminating checks for NULL values from the selection expression and thus simplifying the optimization for unique checking. Here is a comparison of the old and new optimizer strategies. In this example a UNIQUE constraint ("UNIQUE_A") and index on column A is used to check for uniqueness during an INSERT statement. Note that the optimizer chooses a full range search of the index (i.e. [0:0]). ~S: Constraint "UNIQUE_A" evaluated Cross block of 2 entries Cross block entry 1 Conjunct Firstn Get Retrieval by DBK of relation T_UNIQUE Cross block entry 2 Conjunct Aggregate-F2 Conjunct Index only retrieval of relation T_UNIQUE Index name T_UNIQUE_INDEX_A [0:0] With the simplified UNIQUE constraint ("UNIQUE_B") the optimizer can use a direct lookup of the index (i.e. [1:1]) which reduces the I/O to the index to perform the constraint evaluation. ~S: Constraint "UNIQUE_B" evaluated Cross block of 2 entries Cross block entry 1 Conjunct Firstn Get Retrieval by DBK of relation T_UNIQUE Cross block entry 2 Conjunct Aggregate-F2 Index only retrieval of relation T_UNIQUE Index name T_UNIQUE_INDEX_B [1:1] Upward Compatibility The UNIQUE constraint in prior versions restricted columns to a single NULL value. If you wish to retain this behavior then use the SET DIALECT 'SQLV40' statement before creating new tables or altering existing tables to add UNIQUE constraints. UNIQUE constraints created in previous versions of Oracle Rdb will still perform as in previous versions. Interfaces such as RDO, or the CDD/Repository will continue to define the older style UNIQUE constraint. It is expected that future versions of the Oracle CDD/Repository will implement the new UNIQUE constraint. Database EXPORT and IMPORT will retain the UNIQUE constraint characteristics as defined by the database administrator, regardless of the defined dialect setting. Note RMU Extract Item=Table will not distinguish between the old and new UNIQUE constraints in this release of Rdb. The generated SQL script must be modified to establish the appropriate dialect before using it to create a database. As this new style of UNIQUE constraint is a relaxation of the UNIQUE rules, it is possible to drop the old style UNIQUE constraint and redefine the constraint under the SQL92 dialect. Note that this meaning of UNIQUE (i.e. excluding NULL from the uniqueness test) does not apply to the UNIQUE index which still does not allow duplicate entries for NULL. If a UNIQUE index is currently defined which assists the UNIQUE constraint optimization, the database administrator may wish to drop the index and make it a non-UNIQUE index so that multiple NULLs can be stored. The UNIQUE constraint will still enforce the uniqueness of the data. You can use the SQL SHOW TABLE command to determine which type of UNIQUE constraint is in use. For example, the first example is a UNIQUE constraint created when the default dialect was used (SQLV40). A new description follows the "Unique constraint" text, explaining the interpretation of null values. SQL> SHOW TABLE (CONSTRAINT) T_UNIQUE Information for table T_UNIQUE Table constraints for T_UNIQUE: T_UNIQUE_UNIQUE_B_A Unique constraint Null values are considered the same Table constraint for T_UNIQUE Evaluated on UPDATE, NOT DEFERRABLE Source: UNIQUE (b,a) . . . This second example is a UNIQUE constraint created when the dialect was set to 'SQL92', and the description here indicates that all null values are considered distinct. SQL> SHOW TABLE (CONSTRAINT) T_UNIQUE2 Information for table T_UNIQUE2 Table constraints for T_UNIQUE2: T_UNIQUE2_UNIQUE_B_A Unique constraint Null values are considered distinct Table constraint for T_UNIQUE2 Evaluated on UPDATE, NOT DEFERRABLE Source: UNIQUE (b,a) . . . Additional Constraint Improvements As a side effect of this change, Oracle Rdb also recognizes a larger class of CHECK constraints as being uniqueness checks. The main benefit is that these constraints are no longer executed when a DELETE is executed for the table, because DELETE does not affect the uniqueness of the remaining rows. Such an example would be this CHECK constraint: SQL> create table T_USER_UNIQUE_NEW ( cont> a integer, cont> b integer, cont> constraint unique_ab_new cont> check ((select count(*) cont> from T_USER_UNIQUE_NEW t2 cont> where t2.a = T_USER_UNIQUE_NEW.a and cont> t2.b = T_USER_UNIQUE_NEW.b) <= 1) cont> not deferrable cont> ); In previous versions of Rdb only equality with 1 was recognized as a uniqueness constraint. In this example a comparison of LESS THAN or EQUAL to one also qualifies as a uniqueness constraint. A.5.2 Domain Check Constraints and NULL The VALID IF clause (available in RDO and CDD/Repository) is also used to implement the SQL domain CHECK constraint. However, it implements different semantics from a SQL column CHECK clause as defined by the SQL92 standard. The difference is in the handling of the check expression when it is evaluated as NULL. For instance, a column CHECK constraint (col > 0) fails if the non-null value of "col" exceeds 0. However, a null value does not cause a column constraint failure. On the other hand, a VALID IF (used to implement a domain CHECK constraint) would cause a failure when the expression evaluated to NULL. Oracle Rdb V7.0 now detects that the VALID IF is being used as a domain CHECK constraint and applies the same semantics for NULL as with column CHECK constraints. To inherit this new behavior the domain CHECK constraint must be redefined for all domains in the database. The following example shows the alter clause which redefines the CHECK constraint SQL> alter domain SALARY check (value > 0.00) not deferrable; This ALTER DOMAIN statement will cause the domain to be propagated to all referencing columns. This problem has been corrected in Oracle Rdb Version 7.0 for all new or altered check constraint. CHECK constraints created by previous versions of Rdb will continue to exhibit incorrect (or at least inconsistent) handling of NULL when compared to column CHECK constraints. Note The behavior of CDD or RDO defined constraints is unchanged. The constraint must be defined through the SQL interface to inherit the semantics described by this release note.