SQL语言——完整性
完整性
/*--1. 完整性
广义完整性:语义完整性、并发控制、安全控制、DB故障恢复等
狭义完整性:专指语义完整性
*/
/*--2. 完整性约束条件的一般形式
-- Integrity Constraint ::= (O , P , A , R)
-- O 数据集合:约束的对象(列、多列、元组集合)
-- P 谓词条件:什么样的约束
-- A 触发条件: 什么时候检查
-- R 响应动作:不满足时怎么办
/*--3. SQL支持的约束类型
--(1) 静态约束
-- 列完整性————域完整性约束
-- 表完整性————关系完整性约束
-- Integrity Constraint ::=(O , P , A , R)
-- O 列 或 表(多列)
-- P 需要定义的约束条件
-- A 更新时检查(默认)
-- R 拒绝(默认)
CREATE TABLE tablename
((colname datatype [DEFAULT {default_constant | NULL}]
[col_constr {col_constr...}]
|,table_constr
{,{colname datatype [DEFAULT {default_constant | NULL}]
[col_constr {col_constr...}]
|,table_constr}}
));
-- Col_constr列约束
{NOT NULL | //列值非空
[CONSTRAINT constraintname] //为约束命名,便于以后撤销
{UNIQUE //列值唯一性
| PRIMARY KEY //列为主键
| CHECK (search_cond) //列值满足条件,条件只能使用当前列值
| REFERENCES tablename [(colname)]
[ON DELETE {CASCADE | SET NULL}]
}
}
-- 引用另一个表tablename 的列colname的值,如有ON DELETE CASCADE 或 ON DELETE SET NULL
-- 语句,则删除被引用表的某列值v时,要将本表该列值为v的记录删除或列值更新为null;缺省
-- 无操作
-- table_constr 表约束
[CONSTRAINT constraintname]
{UNIQUE (colname {,colname...})
| PRIMARY KEY (colname {,colname...})
| CHECK(search_condition)
| FOREIGN KEY (colname {,colname...})
REFERENCES tablename[(colname{,colname...})]
[ON DELETE CASCADE]
}
--(2) 动态约束
-- 触发器Trigger : 实现动态约束以及多个元组之间的完整性约束
-- Trigger 是一种过程完整性约束,是一段程序,在特定的时刻被自动触发
--基本语法
CREATE TRIGGER trigger_name BEFORE | AFTER
{INSERT | DELETE | UPDATE [OF colname{,colname...}]}
ON tablename [REFERENCING corr_name_def{,corr_name_def...}]
[FOR EACH ROW | FOR EACH STATEMENT] //对更新操作的每一条结果(前者),或整个更新操作完成(后者)
[WHEN (search_condtion)]
{statement //单行程序直接书写
| BEGIN ATOMIC statement;{statement;...} END} //多行程序用一下方式,保持原子性
语句语义:当某一事件发生时(Before | After) ,对该事件产生的结果(或是每一个元组,或是整个
操作的所有元组),检查条件search_condition ,如果满足条件,则执行后面的程序段
其中,条件或程序段中引用的变量可用corr_name_def来限定。
corr_name_def的定义:
{ OLD [ROW] [AS] old_row_corr_name //更新前的旧元组命别名为
| NEW [ROW] [AS] new_row_corr_name //更新后的新元组命别名为
| OLD TABLE [AS] old_table_corr_name //更新前的旧Table命别名为
| NEW TABLE [AS] new_table_corr_name //更新后的新Table命别名为
}
**/
-- e.g.
-- 列约束
CREATE TABLE student(
s# CHAR(8) NOT NULL UNIQUE,
sname CHAR(10),
ssex CHAR(2) CONSTRAINT ctssex CHECK(ssex = '男' OR ssex = '女'),
sage INTEGER CHECK (sage >= 1 AND sage < 150),
d# CHAR(2) REFERENCES dept(d#) ON DELETE CASCADE,
sclass CHAR(6)
);
-- 表约束
CREATE TABLE course(
cid CHAR(3),
cname CHAR(12),
chours INTEGER,
credit FLOAT(1) CONSTRAINT ctcredit CHECK(credit >= 0.0 AND credit <= 5.0),
tid CHAR(3) REFERENCES teacher(tid) ON DELETE CASCADE,
PRIMARY KEY(cid),
CONSTRAINT ctcc CHECK(chours/credit = 20)
);
--
CREATE TABLE sc(
sid CHAR(8) CHECK(sid IN (SELECT sid FROM student)),
cid CHAR(3) CHECK(cid IN (SELECT cid FROM course)),
score FLOAT(1) CONSTRAINT ctscore CHECK(score >= 0.0 AND score <= 100.0)
);
-- 触发器
-- 设计一个触发器,当进行teacher表更新元组时,使其工资只能升不能降
CREATE TRIGGER teacher_chgsal BEFORE UPDATE OF salary
ON teacher
REFERENCING NEW x,OLD y
FOR EACH ROW WHEN(x.salary < y.salary)
BEGIN
raise_application_error(-20003,'invalid salary on update');
//此语句为Oracle的错误处理函数
END;
-- 当学生每选修一门课,都要在学生表的sum_course 增加1,统计学生选修课的数量
CREATE TIGGER sumc AFTER INSERT sc
REFERENCING NEW ROW newi
FOR EACH ROW
BEGIN
UPDATE student SET sum_course = sum_course+1
WHERE s# = :newi.s#;
END;
完整性
/*--1. 完整性
广义完整性:语义完整性、并发控制、安全控制、DB故障恢复等
狭义完整性:专指语义完整性
*/
/*--2. 完整性约束条件的一般形式
-- Integrity Constraint ::= (O , P , A , R)
-- O 数据集合:约束的对象(列、多列、元组集合)
-- P 谓词条件:什么样的约束
-- A 触发条件: 什么时候检查
-- R 响应动作:不满足时怎么办
/*--3. SQL支持的约束类型
--(1) 静态约束
-- 列完整性————域完整性约束
-- 表完整性————关系完整性约束
-- Integrity Constraint ::=(O , P , A , R)
-- O 列 或 表(多列)
-- P 需要定义的约束条件
-- A 更新时检查(默认)
-- R 拒绝(默认)
CREATE TABLE tablename
((colname datatype [DEFAULT {default_constant | NULL}]
[col_constr {col_constr...}]
|,table_constr
{,{colname datatype [DEFAULT {default_constant | NULL}]
[col_constr {col_constr...}]
|,table_constr}}
));
-- Col_constr列约束
{NOT NULL | //列值非空
[CONSTRAINT constraintname] //为约束命名,便于以后撤销
{UNIQUE //列值唯一性
| PRIMARY KEY //列为主键
| CHECK (search_cond) //列值满足条件,条件只能使用当前列值
| REFERENCES tablename [(colname)]
[ON DELETE {CASCADE | SET NULL}]
}
}
-- 引用另一个表tablename 的列colname的值,如有ON DELETE CASCADE 或 ON DELETE SET NULL
-- 语句,则删除被引用表的某列值v时,要将本表该列值为v的记录删除或列值更新为null;缺省
-- 无操作
-- table_constr 表约束
[CONSTRAINT constraintname]
{UNIQUE (colname {,colname...})
| PRIMARY KEY (colname {,colname...})
| CHECK(search_condition)
| FOREIGN KEY (colname {,colname...})
REFERENCES tablename[(colname{,colname...})]
[ON DELETE CASCADE]
}
--(2) 动态约束
-- 触发器Trigger : 实现动态约束以及多个元组之间的完整性约束
-- Trigger 是一种过程完整性约束,是一段程序,在特定的时刻被自动触发
--基本语法
CREATE TRIGGER trigger_name BEFORE | AFTER
{INSERT | DELETE | UPDATE [OF colname{,colname...}]}
ON tablename [REFERENCING corr_name_def{,corr_name_def...}]
[FOR EACH ROW | FOR EACH STATEMENT] //对更新操作的每一条结果(前者),或整个更新操作完成(后者)
[WHEN (search_condtion)]
{statement //单行程序直接书写
| BEGIN ATOMIC statement;{statement;...} END} //多行程序用一下方式,保持原子性
语句语义:当某一事件发生时(Before | After) ,对该事件产生的结果(或是每一个元组,或是整个
操作的所有元组),检查条件search_condition ,如果满足条件,则执行后面的程序段
其中,条件或程序段中引用的变量可用corr_name_def来限定。
corr_name_def的定义:
{ OLD [ROW] [AS] old_row_corr_name //更新前的旧元组命别名为
| NEW [ROW] [AS] new_row_corr_name //更新后的新元组命别名为
| OLD TABLE [AS] old_table_corr_name //更新前的旧Table命别名为
| NEW TABLE [AS] new_table_corr_name //更新后的新Table命别名为
}
**/
-- e.g.
-- 列约束
CREATE TABLE student(
s# CHAR(8) NOT NULL UNIQUE,
sname CHAR(10),
ssex CHAR(2) CONSTRAINT ctssex CHECK(ssex = '男' OR ssex = '女'),
sage INTEGER CHECK (sage >= 1 AND sage < 150),
d# CHAR(2) REFERENCES dept(d#) ON DELETE CASCADE,
sclass CHAR(6)
);
-- 表约束
CREATE TABLE course(
cid CHAR(3),
cname CHAR(12),
chours INTEGER,
credit FLOAT(1) CONSTRAINT ctcredit CHECK(credit >= 0.0 AND credit <= 5.0),
tid CHAR(3) REFERENCES teacher(tid) ON DELETE CASCADE,
PRIMARY KEY(cid),
CONSTRAINT ctcc CHECK(chours/credit = 20)
);
--
CREATE TABLE sc(
sid CHAR(8) CHECK(sid IN (SELECT sid FROM student)),
cid CHAR(3) CHECK(cid IN (SELECT cid FROM course)),
score FLOAT(1) CONSTRAINT ctscore CHECK(score >= 0.0 AND score <= 100.0)
);
-- 触发器
-- 设计一个触发器,当进行teacher表更新元组时,使其工资只能升不能降
CREATE TRIGGER teacher_chgsal BEFORE UPDATE OF salary
ON teacher
REFERENCING NEW x,OLD y
FOR EACH ROW WHEN(x.salary < y.salary)
BEGIN
raise_application_error(-20003,'invalid salary on update');
//此语句为Oracle的错误处理函数
END;
-- 当学生每选修一门课,都要在学生表的sum_course 增加1,统计学生选修课的数量
CREATE TIGGER sumc AFTER INSERT sc
REFERENCING NEW ROW newi
FOR EACH ROW
BEGIN
UPDATE student SET sum_course = sum_course+1
WHERE s# = :newi.s#;
END;