There are two ways in which a CONSTRAINT can be created at the time of TABLE creation: in line
and out of line.
In this example, we create an anonymous PRIMARY KEY constraint on the column PORT_ID. We
can optionally give that constraint a name by preceding the reserved words PRIMARY KEY with the
reserved word CONSTRAINT, followed by a name we make up according to the rules of naming
database objects, like this:
CREATE TABLE PORTS
(PORT_ID NUMBER CONSTRAINT PORT_ID_PK PRIMARY KEY,
PORT_NAME VARCHAR2(20));
These two approaches are referred to as in line constraints, since in both examples the declaration
of the constraint is included with the column definition.
Heres another in line example. This example creates a table with a NOT
NULL constraint:
CREATE TABLE VENDORS
(VENDOR_ID NUMBER,
VENDOR_NAME VARCHAR2(20),
STATUS NUMBER(1) NOT NULL,
CATEGORY VARCHAR2(5));
Note that if you do not provide a name for a constraint, the system will automatically assign one, and
it will be something like this: SYS_C009981.
After the final column is defined for the table, there is a comma, followed by the reserved words
PRIMARY KEY. Notice that the out of line syntax requires that you indicate which column (or
columns) are affected by the constraint. Since were not in line with the column, the statement
cannot know which column youre intending to constrain, unless you specifically indicate it within the
clause.
Heres an out of line example that names the constraint:
CREATE TABLE PORTS
(PORT_ID NUMBER,
PORT_NAME VARCHAR2(20),
CONSTRAINT PORT_ID_PK PRIMARY KEY (PORT_ID) );
This example gives the constraint a name that weve chosen. As is the case with in line constraints,
any out of line constraints that you do not provide with a name will be named automatically by the
system.
Afterward, we can ALTER the table to add a constraint by modifying the definition for a column:
ALTER TABLE PORTS
MODIFY PORT_ID PRIMARY KEY;
In the preceding code, were modifying the declaration of the column itself by adding the primary key
and letting the system assign a name. That syntax is the ALTER equivalent to this:
CREATE TABLE PORTS
(PORT_ID NUMBER PRIMARY KEY,
PORT_NAME VARCHAR2(20));
In addition, we can use ALTER to do the same with a constraint name we assign, like this:
ALTER TABLE PORTS
MODIFY PORT_ID CONSTRAINT PORT_ID_PK PRIMARY KEY;
Those are the in line equivalents of ALTER TABLE. Here are the out of line equivalents. First,
depending on a system-defined name:
Either of those will produce error messages if you try to execute either one. No table or constraint
will be created. And yet, the same syntax is perfectly fine for other types of constraints. For example,
heres the UNIQUE constraint:
CREATE TABLE PORTS
(PORT_ID NUMBER,
PORT_NAME VARCHAR2(20),
CONSTRAINT PORT_ID_UN UNIQUE (PORT_ID) );
So NOT NULL cannot be declared with the out of line format. The others can. But wait, theres
more about NOT NULL. This wont work either:
ALTER TABLE PORTS
ADD NOT NULL (PORT_NAME);
Those wont work because they are the ALTER TABLE equivalents for out of line declarations. But
the ALTER TABLE in line equivalents are fine:
So beware. NOT NULL is a bit unusual. Its a valid constraint and can be created using the other
forms of syntax, but not with the out of line format.
NOT NULL
The NOT NULL constraint is very simplewhen applied to a column, it ensures that for any row that
is added to the TABLE, the column on which the NOT NULL constraint is applied shall always be
provided with a value. Meanwhile, the columns datatype ensures that the data entered into the
column is consistent with the
datatypes rules.
UNIQUE
The UNIQUE constraint, when applied to a column, ensures that any data added to the column in
the future will be unique when compared to data already existing in the column. No other row will
possess the same value for that particular column.
A few notes about UNIQUE:
-UNIQUE can be applied to one column or multiple columns.
-UNIQUE, by itself, allows NULL values to be added to the column. It only restricts data thats
provided for the column to being one-of-a-kind for the column.
Note that the PRIMARY KEY constraint represents the combination of NOT
NULL and UNIQUE. Use the PRIMARY KEY constraint instead of the NOT
NULL and UNIQUE constraints if your intent is to create a single unique identifier for each row in the
table.
PRIMARY KEY
The PRIMARY KEY defines one or more columns in a table that will form the unique identifier for
each row of data that is added to the table. The PRIMARY KEY constraint is a combination of the
NOT NULL and UNIQUE constraints.
A table may have only one PRIMARY KEY constraint.
A single-column PRIMARY KEY is the most common form, and it ensures that for all rows of data
added to the table in the future, the column upon which the
PRIMARY KEY constraint has been applied will always contain a value, and that value will always be
unique when compared to existing values that are already in the table for that particular column.
Here is an example of a CREATE TABLE statement that creates a PRIMARY KEY constraint:
In the preceding example, we create a PRIMARY KEY constraint on the EMPLOYEE_ID column. In
this example, weve given the constraint a name of EMPLOYEES_PK. (The PK suffix is not required,
just one of many good design approaches that clarifies to anyone who might review a long list of
database constraints later on that this particular constraint is a primary key.) Now that weve created
this table with the PRIMARY KEY constraint, any row thats added to the EMPLOYEES table in the
future will require a unique value for each row added.
FOREIGN KEY
A FOREIGN KEY constraint applies to one or more columns in a particular table, and works in
conjunction with a second tables PRIMARY KEY constraint. A FOREIGN KEY is the feature that
helps ensure that two tables can relate to each other, and in many ways really represents the
heart and soul, so to speak, of what a relational database is all about.
The FOREIGN KEY constraint does the following:
- It identifies one or more columns in the current table.
- For each of those columns, it also identifies one or more corresponding columns in a second table.
- It ensures that the other table already has a PRIMARY KEY (or unique) constraint on the
corresponding columns in that second table.
- It then ensures that any future values added to the FOREIGN KEY constrained columns of the
current table are already stored in the corresponding columns of the second table.
In other words, a FOREIGN KEY constraint, along with the PRIMARY KEY constraint on the second
referenced table, enforces referential integrity between the two tables. This means that the
constraints work to ensure that any future data that is added to one or both of the tables continues to
support the ability to relate
data from one table to another.
Note: the referenced table is not actually required to have a PRIMARY KEY constraint on the
referenced columns, but only a UNIQUE constraint on the referenced columns. But youll recall that
a PRIMARY KEY constraint is a combination of the UNIQUE and NOT NULL constraints, so the
PRIMARY KEY satisfies the requirement for a UNIQUE constraint.
Lets look at a sample scenario. First, a listing of data in the PORTS table:
PORT_ID PORT_NAME COUNTRY CAPACITY
------- --------- ------- -------1 Baltimore USA 2
2 Charleston USA 2
3 Tampa USA 8
4 Miami USA 6
5 Galveston USA 4
As you might have already surmised, the value for each ships HOME_PORT_ID should correspond
to a PORT_ID value in the PORTS table.
In order to ensure that the two tables only accept incoming rows of data that support this business
rule that requires all HOME_PORT_ID values to be valid PORT_ID values, we can create a
PRIMARY KEY constraint on the PORTS table (or a UNIQUE constraint), and then a FOREIGN KEY
constraint on the SHIPS table that correlates back to the PRIMARY KEY constraint on the PORTS
table.
First, the PORTS table:
01 CREATE TABLE PORTS
02 (PORT_ID NUMBER,
03 PORT_NAME VARCHAR2(20),
04 COUNTRY VARCHAR2(40),
05 CAPACITY NUMBER,
06 CONSTRAINT PORT_PK PRIMARY KEY (PORT_ID));
Note that the foreign key constraint clause in the CREATE TABLE SHIPS statement starts on line 11
and continues through line 12. It references the PORTS table and the PORTS tables PORT_ID
column, which already has a PRIMARY KEY constraint applied to it. If it did not already have either a
PRIMARY KEY constraint or a UNIQUE constraint on it, then the CREATE TABLE SHIPS statement
would result in an error and let you know that the PORTS table already must exist and must have a
PRIMARY KEY or UNIQUE constraint on the PORT_ID column.
The FOREIGN KEY on SHIPS makes sure that any row added to the SHIPS table will only accept
values for HOME_PORT_ID if that value already exists in the PORTS table. Note that the
HOME_PORT_ID value is not requiredif your goal is to ensure that the HOME_PORT_ID value is
always provided, youll have to also
add a NOT NULL constraint on HOME_PORT_ID as well as FOREIGN KEY. This is one way to do
that:
07 CREATE TABLE SHIPS
08 (SHIP_ID NUMBER,
09 SHIP_NAME VARCHAR2(20),
10 HOME_PORT_ID NUMBER NOT NULL,
11 CONSTRAINT SHIPS_PORTS_FK FOREIGN KEY (HOME_PORT_ID)
12 REFERENCES PORTS (PORT_ID));
CHECK
A CHECK constraint attaches an expression to a constraint. In other words, it applies a small bit of
code to define a particular business rule on incoming rows of data. A CHECK constraint may, for
example, restrict incoming data so that all incoming values are required to be greater than some
minimum value, or fall within a set of predetermined options. A CHECK constraint can ensure that a
twocharacter column only accepts valid abbreviations for American states, for example, or that the
date entered in one column is always greater than the date entered in another column.
Heres an example of a CHECK constraint that only allows rows in the VENDORS table with a
STATUS value of either 4 or 5.
CREATE TABLE VENDORS
(VENDOR_ID NUMBER,
VENDOR_NAME VARCHAR2(20),
STATUS NUMBER(1) CHECK (STATUS IN (4,5)),
CATEGORY VARCHAR2(5));
While rows may be added to VENDORS with no STATUS value, they can only be given a STATUS
value if it is either 4 or 5.
Any valid SQL expression may be used in a CHECK constraint.
Multiple Constraints
A table may be declared with multiple constraints. Heres an example:
CREATE TABLE VENDORS
(VENDOR_ID NUMBER CONSTRAINT VENDOR_ID_PK PRIMARY KEY,
VENDOR_NAME VARCHAR2(20) NOT NULL,
STATUS NUMBER(1) CONSTRAINT STATUS_NN NOT NULL,
CATEGORY VARCHAR2(20),
CONSTRAINT STATUS_CK CHECK (STATUS IN (4, 5)),
CONSTRAINT CATEGORY_CK CHECK
(CATEGORY IN ('Active','Suspended','Inactive')));
Datatype Restrictions
There are some restrictions on some constraints. These restrictions mean that the datatypes
identified cannot and will not receive a constraint applied against them if they are of the types
indicated in the table with a NO in the appropriate field. For example, the PRIMARY KEY constraint
cannot include any columns with a datatype of BLOB, CLOB, or TIMESTAMP WITH TIME ZONE.
(Note, however, that constraints may be applied to columns that have the datatype of TIMESTAMP
WITH LOCAL TIME ZONE.)