6 SQL Tutorial I
6 SQL Tutorial I
SQL (Structured Query Language) is a database sublanguage for querying and modifying relational
databases. It was developed by IBM Research in the mid 70's and standardized by ANSI in 1986.
The Relational Model defines two root languages for accessing a relational database -- Relational
Algebra and Relational Calculus. Relational Algebra is a low-level, operator-oriented language.
Creating a query in Relational Algebra involves combining relational operators using algebraic
notation. Relational Calculus is a high-level, declarative language. Creating a query in Relational
Calculus involves describing what results are desired.
SQL is a version of Relational Calculus. The basic structure in SQL is the statement. Semicolons
separate multiple SQL statements.
I. SQL-Data Statements
SQL-Data Statements perform query and modification on database tables and columns. This subset
of SQL is also called the Data Manipulation Language for SQL (SQL DML).
The SQL SELECT statement queries data from tables in the database. The statement begins with the
SELECT keyword. The basic SELECT statement has 3 clauses:
SELECT
FROM
WHERE
The SELECT clause specifies the table columns that are retrieved. The FROM clause specifies the
tables accessed. The WHERE clause specifies which table rows are used. The WHERE clause is
optional; if missing, all table rows are used.
For example,
The WHERE clause filters the rows of the FROM table to use those whose city column
contains Rome. This chooses a single row from s:
The SELECT clause retrieves the name column from the rows filtered by the WHERE
clause:
name
Mario
The remainder of this subsection examines the 3 major clauses of the SELECT statement, detailing
their syntax and semantics:
SELECT Clause
The SELECT clause is mandatory. It specifies a list of columns to be retrieved from the tables in the
FROM clause. It has the following general format:
SELECT [ALL|DISTINCT] select-list
select-list is a list of column names separated by commas. The ALL and DISTINCT specifiers are
optional. DISTINCT specifies that duplicate rows are discarded. A duplicate row is when each
corresponding select-list column has the same value. The default is ALL, which retains duplicate
rows.
For example,
A special select list consisting of a single '*' requests all columns in all tables in the FROM clause.
For example,
SELECT * FROM sp
An unqualified * cannot be combined with other elements in the select list; it must be stand alone.
However, a qualified * can be combined with other elements. For example,
FROM Clause
The FROM clause always follows the SELECT clause. It lists the tables accessed by the query. For
example,
SELECT * FROM s
When the From List contains multiple tables, commas separate the table names. For example,
SELECT sp.*, city
FROM sp, s
WHERE sp.sno=s.sno
When the From List has multiple tables, they must be joined together.
Correlation Names
Like columns in the select list, tables in the from list can be renamed by following the table name
with the new name. For example,
SELECT supplier.name FROM s supplier
The new name is known as the correlation (or range) name for the table. Self joins require
correlation names.
WHERE Clause
The WHERE clause is optional. When specified, it always follows the FROM clause. The WHERE
clause filters rows from the FROM clause tables. Omitting the WHERE clause specifies that all rows
are used.
The predicate evaluates to a SQL logical value -- true, false or unknown. The most basic predicate
is a comparison:
color = 'Red'
This predicate returns:
Nahason Matoke 3 MMUST
true -- if the color column contains the string value -- 'Red',
false -- if the color column contains another string value (not 'Red'), or
unknown -- if the color column contains null.
Generally, a comparison expression compares the contents of a table column to a literal, as above. A
comparison expression may also compare two columns to each other. Table joins use this type of
comparison.
The = (equals) comparison operator compares two values for equality. Additional comparison
operators are:
For example,
SELECT * FROM sp WHERE qty >= 200
sno pno qty
S2 P1 200
S3 P1 1000
S3 P2 200
Note: In the sp table, the qty column for one of the rows contains null. The comparison - qty >= 200,
evaluates to unknown for this row. In the final result of a query, rows with a WHERE clause
evaluating to unknown (or false) are eliminated (filtered out).
Both operands of a comparison should be the same data type, however automatic conversions are
performed between numeric, datetime and interval types. The CAST expression provides explicit
type conversions;
Extended Comparisons
In addition to the basic comparisons described above, SQL supports extended comparison operators
-- BETWEEN, IN, LIKE and IS NULL.
BETWEEN Operator
The BETWEEN operator implements a range comparison, that is, it tests whether a value is
between two other values. BETWEEN comparisons have the following format:
This comparison tests if value-1 is greater than or equal to value-2 and less than or equal to
value-3. It is equivalent to the following predicate:
For example,
IN Operator
The IN operator implements comparison to a list of values, that is, it tests whether a value
matches any value in a list of values. IN comparisons have the following general format:
This comparison tests if value-1 matches value-2 or matches value-3, and so on. It is
equivalent to the following logical predicate:
or if NOT is included:
For example,
LIKE Operator
The LIKE operator implements a pattern match comparison, that is, it matches a string value
against a pattern string containing wild-card characters.
The wild-card characters for LIKE are percent -- '%' and underscore -- '_'. Underscore
matches any single character. Percent matches zero or more characters.
Examples,
All values must be string (character). This comparison uses value-2 as a pattern to match
value-1. The optional ESCAPE sub-clause specifies an escape character for the pattern,
allowing the pattern to use '%' and '_' (and the escape character) for matching. The ESCAPE
value must be a single character string. In the pattern, the ESCAPE character precedes any
character to be escaped.
is equivalent to:
IS NULL Operator
A database null in a table column has a special meaning -- the value of the column is not
currently known (missing), however its value may be known at a later time. A database null
may represent any value in the future, but the value is not available at this time. Since two
null columns may eventually be assigned different values, one null can't be compared to
another in the conventional way. The following syntax is illegal in SQL:
A special comparison operator -- IS NULL, tests a column for null. It has the following
general format:
This comparison returns true if value-1 contains a null and false otherwise. The optional
NOT reverses the result:
is equivalent to:
For example,
Logical Operators
The logical operators are AND, OR, NOT. They take logical expressions as operands and produce a
logical result (True, False, Unknown). In logical expressions, parentheses are used for grouping.
AND Operator
The AND operator combines two logical operands. The operands are comparisons or logical
expressions. It has the following general format:
AND returns:
AND T F U AND
Input 1 Input 2
T T F U Result
F F F F True True True
U U F U True False False
False False False
False True False
Unknown Unknown Unknown
Unknown True Unknown
Unknown False False
True Unknown Unknown
False Unknown False
For example,
SELECT *
FROM sp
WHERE sno='S3' AND qty < 500
sno pno qty
S3 P2 200
OR Operator
The OR operator combines two logical operands. The operands are comparisons or logical
expressions. It has the following general format:
predicate-1 OR predicate-2
OR T F U OR
Input 1 Input 2
T T T T Result
F T F U True True True
U T U U True False True
False False False
False True True
Unknown Unknown Unknown
Unknown True True
Unknown False Unknown
True Unknown True
False Unknown Unknown
For example,
SELECT *
FROM s
WHERE sno='S3' OR city = 'London'
sno name city
S2 John London
S3 Mario Rome
a OR b AND c
is equivalent to:
a OR (b AND c)
NOT Operator
The NOT operator inverts the result of a comparison expression or a logical expression. It
has the following general format:
NOT predicate-1
Example query:
SELECT *
FROM sp
WHERE NOT sno = 'S3'
sno pno qty
S1 P1 NULL
S2 P1 200
The other SQL-Data Statements (DML) are covered in -- SQL Modification Statements:
The SQL Modification Statements make changes to database data in tables and columns. There are 3
modification statements:
INSERT Statement
The INSERT Statement adds one or more rows to a table. It has two formats:
INSERT INTO table-1 [(column-list)] VALUES (value-list)
and,
INSERT INTO table-1 [(column-list)] (query-specification)
The first form inserts a single row into table-1 and explicitly specifies the column values for the row.
The second form uses the result of query-specification to insert one or more rows into table-1. The
result rows from the query are the rows added to the insert table. Note: the query cannot reference
table-1.
If the optional column-list is missing, the default column list is substituted. The default column list
contains all columns in table-1 in the order they were declared in CREATE TABLE, or CREATE
VIEW.
VALUES Clause
The VALUES Clause in the INSERT Statement provides a set of values to place in the columns of a
new row. It has the following general format:
VALUES ( value-1 [, value-2] ... )
value-1 and value-2 are Literal Values or Scalar Expressions involving literals. They can also
specify NULL.
The values list in the VALUES clause must match the explicit or implicit column list for INSERT in
degree (number of items). They must also match the data type of corresponding column or be
convertible to that data type.
INSERT Examples
INSERT INTO p (pno, color) VALUES ('P4', 'Brown')
Before After
pno descr color pno descr color
P1 Widget Blue P1 Widget Blue
P2 Widget Red P2 Widget Red
=>
P3 Dongle Green P3 Dongle Green
P4 NULL Brown
INSERT INTO sp
SELECT s.sno, p.pno, 500
FROM s, p
WHERE p.color='Green' AND s.city='London'
Before After
sno pno qty sno pno qty
S1 P1 NULL S1 P1 NULL
S2 P1 200 S2 P1 200
S3 P1 1000 => S3 P1 1000
S3 P2 200 S3 P2 200
S2 P3 500
UPDATE Statement
The UPDATE statement modifies columns in selected table rows. It has the following general
format:
UPDATE table-1 SET set-list [WHERE predicate]
The optional WHERE Clause has the same format as in the SELECT Statement. as WHERE Clause.
The WHERE clause chooses which table rows to update. If it is missing, all rows are in table-1 are
updated.
SET Clause
The SET Clause in the UPDATE Statement updates (assigns new value to) columns in the selected
table rows. It has the following general format:
SET column-1 = value-1 [, column-2 = value-2] ...
column-1 and column-2 are columns in the Update table. value-1 and value-2 are expressions that
can reference columns from the update table. They also can be the keyword -- NULL, to set the
column to null.
Since the assignment expressions can reference columns from the current row, the expressions are
evaluated first. After the values of all Set expressions have been computed, they are then assigned to
the referenced columns. This avoids results dependent on the order of processing.
UPDATE Examples
UPDATE sp SET qty = qty + 20
Before After
sno pno qty sno pno qty
S1 P1 NULL S1 P1 NULL
S2 P1 200 S2 P1 220
=>
S3 P1 1000 S3 P1 1020
S3 P2 200 S3 P2 220
UPDATE s
SET name = 'Tony', city = 'Milan'
WHERE sno = 'S3'
Before After
sno name city sno name city
S1 Pierre Paris S1 Pierre Paris
S2 John London => S2 John London
S3 Mario Rome S3 Tony Milan
DELETE Statement
The DELETE Statement removes selected rows from a table. It has the following general format:
DELETE FROM table-1 [WHERE predicate]
The optional WHERE Clause has the same format as in the SELECT Statement. See WHERE
Clause. The WHERE clause chooses which table rows to delete. If it is missing, all rows are in
table-1 are removed.
The WHERE Clause predicate can contain subqueries, but the subqueries cannot reference table-1.
This prevents situations where results are dependent on the order of processing.
DELETE Examples
DELETE FROM sp WHERE pno = 'P1'
Before After
sno pno qty sno pno qty
S1 P1 NULL => S3 P2 200
COMMIT Statement -- commit (make persistent) all changes for the current transaction
ROLLBACK Statement -- roll back (rescind) all changes for the current transaction
Transaction Overview
A database transaction is a larger unit that frames multiple SQL statements. A transaction ensures
that the action of the framed statements is atomic with respect to recovery.
A transaction is a group of commands that change the data stored in a database, it is treated as a
single unit. It ensures that, either all of the commands succeed, or none at all. That means if one of
the commands in the transaction fails, all of the commands fail, and any data that was modified in
the database is rolled back. Hence the transactions maintains the integrity of the data in the database.
A SQL Modification Statement has limited effect. A given statement can only directly modify the
contents of a single table (Referential Integrity effects may cause indirect modification of other
tables.) The upshot is that operations which require modification of several tables must involve
multiple modification statements. A classic example is a bank operation that transfers funds from
one type of account to another, requiring updates to 2 tables. Transactions provide a way to group
these multiple statements in one atomic unit.
In SQL92, there is no BEGIN TRANSACTION statement. A transaction begins with the execution
of a SQL-Data statement when there is no current transaction. All subsequent SQL-Data statements
until COMMIT or ROLLBACK become part of the transaction. Execution of a COMMIT Statement
or ROLLBACK Statement completes the current transaction. A subsequent SQL-Data statement
starts a new transaction.
In terms of direct effect on the database, it is the SQL Modification Statements that are the main
consideration since they change data. The total set of changes to the database by the modification
statements in a transaction are treated as an atomic unit through the actions of the transaction. The
set of changes either:
The DBMS must ensure that the effect of a transaction is not partial. All changes in a transaction
must be made persistent, or no changes from the transaction must be made persistent.
Transaction Isolation
In most cases, transactions are executed under a client connection to the DBMS. Multiple client
connections can initiate transactions at the same time. This is known as concurrent transactions.
In the relational model, each transaction is completely isolated from other active transactions. After
initiation, a transaction can only see changes to the database made by transactions committed prior to
starting the new transaction. Changes made by concurrent transactions are not seen by SQL DML
query and modification statements. This is known as full isolation or Serializable transactions.
SQL92 defines Serializable for transactions. However, fully serialized transactions can impact
performance. For this reason, SQL92 allows additional isolation modes that reduce the isolation
between concurrent transactions. SQL92 defines 3 other isolation modes, but support by existing
DBMSs is often incomplete and doesn't always match the SQL92 modes. Check the documentation
of your DBMS for more details.
Transaction isolation controls the visibility of changes between transactions in different sessions
(connections). It determines if queries in one session can see changes made by a transaction in
another session. There are 4 levels of transaction isolation. The level providing the greatest isolation
from other transactions is Serializable.
At transaction isolation level Serializable, a transaction is fully isolated from changes made by other
sessions. Queries issued under Serializable transactions cannot see any subsequent changes,
committed or not, from other transactions. The effect is the same as if transactions were serial, that
is, each transaction completing before another one is begun.
At the opposite end of the spectrum is Read Uncommitted. It is the lowest level of isolation. With
Read Uncommitted, a session can read (query) subsequent changes made by other sessions, either
committed or uncommitted. Read uncommitted transactions have the following characteristics:
Dirty Read -- a session can read rows changed by transactions in other sessions that have not
been committed. If the other session then rolls back its transaction, subsequent reads of the
same rows will find column values returned to previous values, deleted rows reappearing and
rows inserted by the other transaction missing.
Non-repeatable Read -- a session can read a row in a transaction. Another session then
changes the row (UPDATE or DELETE) and commits its transaction. If the first session
subsequently re-reads the row in the same transaction, it will see the change.
Phantoms -- a session can read a set of rows in a transaction that satisfies a search condition
(which might be all rows). Another session then generates a row (INSERT) that satisfies the
search condition and commits its transaction. If the first session subsequently repeats the
search in the same transaction, it will see the new row.
In Read Committed isolation level, Dirty Reads are not possible, but Non-repeatable Reads and
Phantoms are possible. In Repeatable Read isolation level, Dirty Reads and Non-repeatable Reads
are not possible but Phantoms are. In Serializable, Dirty Reads, Non-repeatable Reads, and
Phantoms are not possible.
Note: SQL92 defines the SET TRANSACTION statement to set the transaction isolation level for a
session, but most DBMSs support a function/method in the Client API as an alternative.
SQL92 leaves the choice up to the individual DBMS. It is implementation defined behavior.
COMMIT Statement
The COMMIT Statement terminates the current transaction and makes all changes under the
transaction persistent. It commits the changes to the database. The COMMIT statement has the
following general format:
COMMIT [WORK]
WORK is an optional keyword that does not change the semantics of COMMIT.
CREATE TABLE Statement -- create a new base table in the current schema
CREATE VIEW Statement -- create a new view table in the current schema
DROP TABLE Statement -- remove a base table from the current schema
DROP VIEW Statement -- remove a view table from the current schema
GRANT Statement -- grant access privileges for objects in the current schema to other users
REVOKE Statement -- revoke previously granted access privileges for objects in the current
schema from other users
Schema Overview
A relational database contains a catalog that describes the various elements in the system. The
catalog divides the database into sub-databases known as schemas. Within each schema are database
objects -- tables, views and privileges.
The catalog itself is a set of tables with its own schema name - definition_schema. Tables in the
catalog cannot be modified directly. They are modified indirectly with SQL-Schema statements.
Tables
The database table is the root structure in the relational model and in SQL. A table (called a relation
in relational) consists of rows and columns. In relational, rows are called tuples and columns are
called attributes. Tables are often displayed in a flat format, with columns arrayed horizontally and
rows vertically:
Columns
R
o
w
Database tables are a logical structure with no implied physical characteristics. Primary among the
various logical tables is the base table. A base table is persistent and self contained, that is, all data is
part of the table itself with no information dynamically derived from other tables.
A table has a fixed set of columns. The columns in a base table are not accessed positionally but by
name, which must be unique among the columns of the table. Each column has a defined data type,
A table has 0 or more rows. A row in a base table has a value or null for each column in the table.
The rows in a table have no defined ordering and are not accessed positionally. A table row is
accessed and identified by the values in its columns.
In SQL92, base tables can have duplicate rows (rows where each column has the same value or
null). However, the relational model does not recognize tables with duplicate rows as valid base
tables (relations). The relational model requires that each base table have a unique identifier, known
as the Primary Key. The primary key for a table is a designated set of columns which have a unique
value for each table row. For a discussion of Primary Keys, see Entity Integrity under CREATE
TABLE below.
A base table is defined using the CREATE TABLE Statement. This statement places the table
description in the catalog and initializes an internal entity for the actual representation of the base
table.
Other types of tables in the system are derived tables. SQL-Data statements use internally derived
tables in computing results. A query is in fact a derived table. For instance, the query operator -
Union, combines two derived tables to produce a third one. Much of the power of SQL comes from
the fact that its higher level operations are performed on tables and produce a table as their result.
Derived tables are less constrained than base tables. Column names are not required and need not be
unique. Derived tables may have duplicate rows. Views are a type of derived table that are cataloged
in the database. See Views below.
Views
A view is a derived table registered in the catalog. A view is defined using a SQL query. The view is
dynamically derived, that is, its contents are materialized for each use. Views are added to the
catalog with the CREATE VIEW Statement.
ZX
A SQL Modification Statement can operate on a view if it is an updatable view. An updatable view
has the following restrictions on its defining query:
The query FROM clause can reference a single table (or view)
Subqueries are acceptable in updatable views but cannot reference the underlying base table for the
view's FROM clause.
Privileges
SQL92 defines a SQL-agent as an implementation-dependent entity that causes the execution of
SQL statements. Prior to execution of SQL statements, the SQL-agent must establish an
authorization identifier for database access. An authorization identifier is commonly called a user
name.
A DBMS user may access database objects (tables, columns, views) as allowed by the privileges
assigned to that specific authorization identifier. Access privileges may be granted by the system
(automatic) or by other users.
All privileges on a table to the user that created the table. This includes the privilege to grant
privileges on the table to other users.
SELECT (readonly) privilege on the catalog (the tables in the schema - definition_schema).
This is granted to all users.
User granted privileges cover privileges to access and modify tables and their columns. Privileges
can be granted for specific SQL-Data Statements -- SELECT, INSERT, UPDATE, DELETE.
Constraints
Constraint specifications add additional restrictions on the contents of the table. They are
automatically enforced by the DBMS. The column constraints are:
NOT NULL -- specifies that the column can't be set to null. If this constraint is not specified,
the column is nullable, that is, it can be set to null. Normally, primary key columns are
declared as NOT NULL.
PRIMARY KEY -- specifies that this column is the only column in the primary key. There
can be only one primary key declaration in a CREATE TABLE. For primary keys with
multiple columns, use the PRIMARY KEY table constraint. See Entity Integrity below for a
detailed description of primary keys.
UNIQUE -- specifies that this column has a unique value or null for all rows of the table.
REFERENCES -- specifies that this column is the only column in a foreign key. For foreign
keys with multiple columns, use the FOREIGN KEY table constraint. See Referential
Integrity below for a detailed description of primary keys.
CHECK -- specifies a user defined constraint on the table. See the table constraint - CHECK,
below.
PRIMARY KEY -- specifies the set of columns that comprise the primary key. There can be
only one primary key declaration in a CREATE TABLE Statement. See Entity Integrity
below for a detailed description of primary keys.
UNIQUE -- specifies that a set of columns have unique values (or nulls) for all rows in the
table. The UNIQUE specifier is followed by a parenthesized list of column names, separated
by commas.
FOREIGN KEY -- specifies the set of columns in a foreign key. See Referential Integrity
below for a detailed description of foreign keys.
CHECK -- specifies a user defined constraint, known as a check condition. The CHECK
specifier is followed by a predicate enclosed in parentheses. For Intermediate Level SQL92,
the CHECK predicate can only reference columns from the current table row, with no
subqueries. Many DBMSs support subqueries in the check predicate.
The check predicate must evaluate to not False (that is, the result must be True or Unknown)
before a modification or addition of a row takes place. The check is effectively made on the
contents of the table after the modification. For INSERT Statements, the predicate is
evaluated as if the INSERT row were added to the table. For UPDATE Statements, the
predicate is evaluated as if the row were updated. For DELETE Statements, the predicate is
evaluated as if the row were deleted (Note: A check predicate is only useful for DELETE if a
self-referencing subquery is used.)
Data Type
This subsection describes data type specifications. The data type categories are:
Character (String) -- fixed or variable length character strings. The character set is
implementation defined but often defaults to ASCII.
Nahason Matoke 18 MMUST
Numeric -- values representing numeric quantities. Numeric values are divided into these two
broad categories:
o Exact (also known as fixed-point) -- Exact numeric values have a fixed number of
digits to the left of the decimal point and a fixed number of digits to the right (the
scale). The total number of digits on both sides of the decimal are the precision. A
special subset of exact numeric types with a scale of 0 is called integer.
o Approximate (also known as floating-point) -- Approximate numeric values that have
a fixed precision (number of digits) but a floating decimal point.
Datetime -- Datetime values include calendar and clock values (Date, Time, Timestamp) and
intervals. The datetime types are:
o Date -- calendar date with year, month and day
o Time -- clock time with hour, minute, second and fraction of second, plus a timezone
component (adjustment in hours, minutes)
o Timestamp -- combination calendar date and clock time with year, month, day, hour,
minute, second and fraction of second, plus a timezone component (adjustment in
hours, minutes)
o Interval -- intervals represent time and date intervals. They are signed. An interval
value can contain a subset of the interval fields, for example - hour to minute, year,
day to second. Interval types are subdivided into:
year-month intervals -- may contain years, months or combination
years/months value.
day-time intervals -- days, hours, minutes, seconds, fractions of second.
length specifies the number of characters for fixed size strings (CHAR,
CHARACTER); spaces are supplied for shorter strings. If length is missing for fixed
size strings, the default length is 1. For variable size strings (VARCHAR,
CHARACTER VARYING), length is the maximum size of the string. Strings
exceeding length are truncated on the right.
Numeric
SMALLINT
INT
INTEGER
The integer types have default binary precision -- 15 for SMALLINT and 31 for INT,
INTEGER.
Fixed point types have a decimal precision (total number of digits) and scale (which
cannot exceed the precision). The default scale is 0. NUMERIC scales must be
FLOAT [(precision)]
REAL
DOUBLE
The floating point types have a binary precision (maximum significant binary digits).
Precision values are implementation dependent for REAL and DOUBLE, although
the standard states that the default precision for DOUBLE must be larger than for
REAL. FLOAT also uses an implementation defined default for precision (commonly
this is the same as for REAL), but the binary precision for FLOAT can be explicit.
Datetime
DATE
TIME [(scale)] [WITH TIME ZONE]
TIMESTAMP [(scale)] [WITH TIME ZONE]
TIME and TIMESTAMP allow an optional seconds fraction (scale). The default scale
for TIME is 0, for TIMESTAMP 6. The optional WITH TIME ZONE specifier
indicates that the timezone adjustment is stored with the value; if omitted, the current
system timezone is assumed.
INTERVAL interval-qualifier
Interval Qualifier
An interval qualifier defines the specific type of an interval value. The qualifier for an interval type
declares the sub-fields that comprise the interval, the precision of the highest (left-most) sub-field
and the scale of the SECOND sub-field (if any).
Intervals are divided into sub-types -- year-month intervals and day-time intervals. Year-month
intervals can only contain the sub-fields - year and month. Day-time intervals can contain day, hour,
minute, second. The interval qualifier has the following formats:
MONTH [(precision)]
Entity Integrity
As mentioned earlier, the relational model requires that each base table have a Primary Key. SQL92,
on the other hand, allows a table to created without a primary key. The advice here is to create all
tables with primary keys.
For a given row, the set of values for the primary key columns must be unique from all other
rows in the table,
No primary key column can contain a null, and
A table can have only one primary key (set of primary key columns).
Note: SQL92 does not require the second restriction on nulls in the primary key. However, it is
required for a relational system.
Entity Integrity (Primary Keys) is enforced by the DBMS and ensures that every row has a proper
unique identifier. The contents of any column in the table with Entity Integrity can be uniquely
accessed with 3 pieces of information:
table identifier
primary key value
column name
This capability is crucial to a relational system. Having a clear, consistent identifier for table rows
(and their columns) distinguishes relational systems from all others. It allows the establishment of
relationships between tables, also crucial to relational systems. This is discussed below under
Referential Integrity.
The primary key constraint in the CREATE STATEMENT has two forms. When the primary key
consists of a single column, it can be declared as a column constraint, simply - PRIMARY KEY,
attached to the column descriptor. For example:
Referential Integrity
Foreign keys provide relationships between tables in the database. In relational, a foreign key in a
table is a set of columns that reference the primary key of another table. For each row in the
referencing table, the foreign key must match an existing primary key in the referenced table. The
enforcement of this constraint is known as Referential Integrity.
The columns of a foreign key must match in number and type the columns of the primary key
in the referenced table.
The values of the foreign key columns in each row of the referencing table must match the
values of the corresponding primary key columns for a row in the referenced table.
The one exception to the second restriction is when the foreign key columns for a row contain nulls.
Since primary keys should not contain nulls, a foreign key with nulls cannot match any row in the
referenced table. However, a row with a foreign key where any foreign key column contains null is
allowed in the referencing table. No corresponding primary key value in the referenced table is
required when any one (or more) of the foreign key columns is null. Other columns in the foreign
Like other constraints, the referential integrity constraint restricts the contents of the referencing
table, but it also may in effect restrict the contents of the referenced table. When a row in a table is
referenced (through its primary key) by a foreign key in a row in another table, operations that affect
its primary key columns have side-effects and may restrict the operation. Changing the primary key
of or deleting a row which has referencing foreign keys would violate the referential integrity
constraints on the referencing table if allowed to proceed. This is handled in two ways,
The referenced table is restricted from making the change (and violating referential integrity
in the referencing table), or
Rows in the referencing table are modified so the referential integrity constraint is
maintained.
These actions are controlled by the referential integrity effects declarations, called referential
triggers by SQL92. The referential integrity effect actions defined for SQL are:
NO ACTION -- the change to the referenced (primary key) table is not performed. This is the
default.
CASCADE -- the change to the referenced table is propagated to the referencing (foreign
key) table.
SET NULL -- the foreign key columns in the referencing table are set to null.
Update and delete have separate action declarations. For CASCADE, update and delete also operate
differently:
For update (the primary key column values have been modified), the corresponding foreign
key columns for referencing rows are set to the new values.
For delete (the primary key row is deleted), the referencing rows are deleted.
A referential integrity constraint in the CREATE STATEMENT has two forms. When the foreign
key consists of a single column, it can be declared as a column constraint, like:
column-descr REFERENCES references-specification
As a table constraint, it has the following format:
FOREIGN KEY (column-list) REFERENCES references-specification
column-list is the referencing table columns that comprise the foreign key. Commas separate column
names in the list. Their order must match the explicit or implicit column list in the references-
specification.
table-2 [ ( referenced-columns ) ]
[ ON UPDATE { CASCADE | SET NULL | NO ACTION }]
[ ON DELETE { CASCADE | SET NULL | NO ACTION }]
The order of the ON UPDATE and ON DELETE clauses may be reversed. These clauses declare the
effect action when the referenced primary key is updated or deleted. The default for ON UPDATE
and ON DELETE is NO ACTION.
table-2 is the referenced table name (primary key table). The optional referenced-columns list the
columns of the referenced primary key. Commas separate column names in the list. The default is
the primary key list in declaration order.
CREATE TABLE p
(pno VARCHAR(5) NOT NULL PRIMARY KEY,
descr VARCHAR(16),
color VARCHAR(8)
)
CREATE TABLE sp
(sno VARCHAR(5) NOT NULL REFERENCES s,
pno VARCHAR(5) NOT NULL REFERENCES p,
qty INT,
PRIMARY KEY (sno, pno)
)
Create for sp with a constraint that the qty column can't be negative:
CREATE TABLE sp
(sno VARCHAR(5) NOT NULL REFERENCES s,
pno VARCHAR(5) NOT NULL REFERENCES p,
qty INT CHECK (qty >= 0),
PRIMARY KEY (sno, pno)
)
column-list must have the same number of columns as the select list in query-1. If column-list is
omitted, all items in the select list of query-1 must be named. In either case, duplicate column names
are not allowed for a view.
The optional WITH CHECK OPTION clause only applies to updatable views. It affects SQL
INSERT and UPDATE statements. If WITH CHECK OPTION is specified, the WHERE predicate
for query-1 must evaluate to true for the added row or the changed row.
The CASCADED and LOCAL specifiers apply when the underlying table for query-1 is another
view. CASCADED requests that WITH CHECK OPTION apply to all underlying views (to any
RESTRICT specifies that the table not be dropped if any dependencies exist. If dependencies are
found, an error is returned and the table isn't dropped.
CASCADE specifies that any dependencies are removed before the drop is performed:
RESTRICT specifies that the view not be dropped if any dependencies exist. If dependencies are
found, an error is returned and the view isn't dropped.
CASCADE specifies that any dependencies are removed before the drop is performed:
Views that reference the drop view are dropped, and the sequence is repeated for their
dependencies.
Constraints in base tables that reference this view are dropped; the constraint is dropped but
the table retained.
GRANT Statement
The GRANT Statement grants access privileges for database objects to other users. It has the
following general format:
GRANT privilege-list ON [TABLE] object-list TO user-list
privilege-list is either ALL PRIVILEGES or a comma-separated list of properties: SELECT,
INSERT, UPDATE, DELETE. object-list is a comma-separated list of table and view names. user-
list is either PUBLIC or a comma-separated list of user names.
The GRANT statement grants each privilege in privilege-list for each object (table) in object-list to
each user in user-list. In general, the access privileges apply to all columns in the table or view, but it
is possible to specify a column list with the UPDATE privilege specifier:
The user-list may specify PUBLIC. This is a general grant, applying to all users (and future users) in
the catalog.
The optional specificier WITH GRANT OPTION may follow user-list in the GRANT statement.
WITH GRANT OPTION specifies that, in addition to access privileges, the privilege to grant those
privileges to other users is granted.
REVOKE Statement
The REVOKE Statement revokes access privileges for database objects previously granted to other
users. It has the following general format:
REVOKE privilege-list ON [TABLE] object-list FROM user-list
The REVOKE Statement revokes each privilege in privilege-list for each object (table) in object-list
from each user in user-list. All privileges must have been previously granted.
The user-list may specify PUBLIC. This must apply to a previous GRANT TO PUBLIC.
To determine how many years old each of your pets is, compute the difference in the year part of the
current date and the birth date, then subtract one if the current date occurs earlier in the calendar year
than the birth date. The following query shows, for each pet, the birth date, the current date, and the
age in years.
Here, YEAR() pulls out the year part of a date and RIGHT() pulls off the rightmost five characters
that represent the MM-DD (calendar year) part of the date. The part of the expression that compares the
MM-DD values evaluates to 1 or 0, which adjusts the year difference down a year if CURDATE() occurs
earlier in the year than birth. The full expression is somewhat ungainly, so an alias (age) is used to
make the output column label more meaningful.
The query works, but the result could be scanned more easily if the rows were presented in some
order. This can be done by adding an ORDER BY name clause to sort the output by name:
To sort the output by age rather than name, just use a different ORDER BY clause:
A similar query can be used to determine age at death for animals that have died. You determine
which animals these are by checking whether the death value is NULL. Then, for those with non-
NULL values, compute the difference between the death and birth values:
The query uses death IS NOT NULL rather than death <> NULL because NULL is a special value
that cannot be compared using the usual comparison operators. This is discussed later. See
Section 3.3.4.6, “Working with NULL Values”.
What if you want to know which animals have birthdays next month? For this type of calculation,
year and day are irrelevant; you simply want to extract the month part of the birth column. MySQL
provides several functions for extracting parts of dates, such as YEAR(), MONTH(), and
DAYOFMONTH(). MONTH() is the appropriate function here. To see how it works, run a simple query
that displays the value of both birth and MONTH(birth):
Finding animals with birthdays in the upcoming month is also simple. Suppose that the current
month is April. Then the month value is 4 and you can look for animals born in May (month 5) like
this:
There is a small complication if the current month is December. You cannot merely add one to the
month number (12) and look for animals born in month 13, because there is no such month. Instead,
you look for animals born in January (month 1).
You can write the query so that it works no matter what the current month is, so that you do not have
to use the number for a particular month. DATE_ADD() allows you to add a time interval to a given
date. If you add a month to the value of CURDATE(), then extract the month part with MONTH(), the
result produces the month in which to look for birthdays:
A different way to accomplish the same task is to add 1 to get the next month after the current one
after using the modulo function (MOD) to wrap the month value to 0 if it is currently 12:
Note that MONTH returns a number between 1 and 12. And MOD(something,12) returns a number
between 0 and 11. So the addition has to be after the MOD(), otherwise we would go from November
(11) to January (1).
The NULL value can be surprising until you get used to it. Conceptually, NULL means “a missing
unknown value” and it is treated somewhat differently than other values. To test for NULL, you
cannot use the arithmetic comparison operators such as =, <, or <>. To demonstrate this for yourself,
try the following query:
Clearly you get no meaningful results from these comparisons. Use the IS NULL and IS NOT NULL
operators instead:
Note that in MySQL, 0 or NULL means false and anything else means true. The default truth value
from a boolean operation is 1.
When doing an ORDER BY, NULL values are presented first if you do ORDER BY ... ASC and last if
you do ORDER BY ... DESC.
A common error when working with NULL is to assume that it is not possible to insert a zero or an
empty string into a column defined as NOT NULL, but this is not the case. These are in fact values,
whereas NULL means "not having a value". You can test this easily enough by using IS [NOT] NULL
as shown:
mysql> SELECT 0 IS NULL, 0 IS NOT NULL, '' IS NULL, '' IS NOT NULL;
+-----------+---------------+------------+----------------+
| 0 IS NULL | 0 IS NOT NULL | '' IS NULL | '' IS NOT NULL |
+-----------+---------------+------------+----------------+
| 0 | 1 | 0 | 1 |
+-----------+---------------+------------+----------------+
Thus it is entirely possible to insert a zero or empty string into a NOT NULL column, as these are in
fact NOT NULL. See Section A.5.3, “Problems with NULL Values”.