用户权限是由两个要素组成的:数据库对象和操作类型。
定义存取权限称为授权。
存取控制的对象不仅有数据本身(基本表中的数据、属性列上的数据),还有数据库模式(包括模式、基本表、视图和索引的创建等),

4.2.4授权:授予与收回
GRANT语句向用户授予权限,REVOKE语句收回已经授予用户的权限
1.GRANT
GRANT语句的一般格式为
 

GRANT<权限>[<权限>]……
               ON<对象类型><对象名>[,<对象类型><对象名>]……
               TO<用户>[,<用户>]……
               [WITH GRANT OPTION];
                 其语句为:将对指定操作对象的指定操作权限授予指定的用户。 [例4.1] 把查询student表的权限授给用户UI.
          GRANT SELECT
                  ON TABLE student
                  TO UI;
 [例4.2] 把对student表和course表的全部操作权限授予用户U2和U3.
          GRANT ALL PRIVILEGES
                  ON TABLE student,course
                     TO U2,U3; 
 [例4.3] 把对表sc的查询权限授予所有用户。
          GRANT SELECT 
                  ON TABLE sc
                  TO PUBLIC;
 [例4.4] 把查询student表和修改学生学号的权限授给用户U4。
          GRANT UPDATE(Sno),SELECT
                  ON TABLE student
                  TO U4;
 [例4.5] 把对表sc的INSERT权限授予U5用户,并允许将此权限再授予其他用户。
          GRANT INSERT
            ON TABLE    sc
                  TO U5
                  WITH GRANT OPTION;
                  
 [例4.6] U5可以将此权限授予U6.
         GRANT INSERT
            ON TABLE    sc
                  TO U6
                  WITH GRANT OPTION;
 [例4.7] U6可以将此权限授予U7.
         GRANT INSERT
            ON TABLE    sc
                  TO U7
 --                  WITH GRANT OPTION;
 2.REVOKE(授予用户的权限可以由数据管理员或其他授权者用REVOKE语句收回)
   其语句格式一般为
                 REVOKE <权限>[,<权限>]……
                 ON<对象类型><对象名>[,<对象类型><对象名>]……
                 FROM<用户>[,<用户>]……[CASCADE|RESTRICT];
 [例4.8] 把用户U4修改学生学号的权限收回。
          REVOKE UPDATE(Sno)
                  ON TABLE student
                  FROM U4;
 [例4.9] 收回所有用户对表sc的查询权限。
               REVOKE SELECT
                 ON TABLE sc
                 FROM PUBLIC;
 [例4.10] 把用户U5对sc表的INSERT权限收回。
          REVOKE INSERT
                  ON TABLE sc
                  FROM U5 CASCADE;
                  
 [例4.11] 通过角色来实现将一组权限授予一个用户。
          1.首先创建一个角色R1.
                  CREATE ROLE R1
                  2.然后使用GRANT语句,使角色R1拥有student表的SELECT、UPDATE、INSERT权限。
                  GRANT SELECT,UPDATE,INSERT
                  ON TABLE student
                  TO R1;
                  3.将这个角色授予王平、张明、李玲,使他们具有角色R1所包含的全部权限。
                  GRANT R1
                  TO 王平,张明,李玲;
                  4.当然,也可以一次性地通过R1来收回王平的这三个权限。
                  REVOKE R1
                  FROM 王平;
 [例4.12] 角色的权限修改。
           GRANT DELETE
                     ON TABLE student
                     TO R1
                     使角色R1在原来的基础上增加了student表的DELETE    权限。
                     
 [例4.13] REVOKE SELECT
                ON TABLE student
                  FROM R1;
                  使R1减少了SELECT权限。

第五章 数据库完整性
       数据库完整性是指数据的正确性和相容性。
       为维护数据库的完整性,数据库管理系统必须能够实现如下功能。
           1.提供定义完整性约束条件的机制
           2.提供完整性检查的方法
           3.进行违约处理
5.1.1 定义实体完整性
                     关系模型的实体完整性在CREATE TABLE中用PRIMARY KEY定义。
                          对单属性构成的码有两种说明方法,一种是定义为列级约束条件,另一种是定义为表级约束条件。
                            对多属性构成的码只有一种说明方法,即定义为表级约束条件。 

   

[例5.1]  将student表中的Sno属性定义为码。
           CREATE TABLE student
                             (Sno CHAR(9)PRIMARY KEY,     /*在列级定义主码*/
                                     Sname CHAR(20)NOT NULL,
                                     Ssex CHAR(2),
                                     Sage SMALLINT,
                                     Sdept CHAR(20)
                                     );
         或者
              CREATE TABLE student
                             (Sno CHAR(9),               
                                     Sname CHAR(20)NOT NULL,
                                     Ssex CHAR(2),
                                     Sage SMALLINT,
                                     Sdept CHAR(20),
                                     PRIMARY KEY(Sno)            /*在表级定义主码*/  
                                     );                                
 [例5.2]  将sc表中的Sno/Cno属性组定义为码。
          CREATE TABLE sc
                       (Sno CHAR(9) NOT NULL,
                              Cno CHAR(4) NOT NULL,
                              Grade SMALLINT,
                              PRIMARY KEY(Sno,Cno)          /*只能在表级定义主码*/
                             );
 5.1.2 实体完整性检查和违约处理
 5.2.1 定义参照完整性
       关系模型的参照完整性在CREATE TABLE中用FOREIGN KEY短语定义哪些列为外码,用REFERENCES短语指明这些外码参照哪些表的主码。                            
 [例5.3]  定义sc中的参照完整性。
          CREATE TABLE SC
                  (Sno CHAR(9) NOT NULL,
                  Cno CHAR(4) NOT NULL,
                  Grade SMALLINT,
                  PRIMARY KEY (Sno,Cno),                                //在表级定义实体完整性//
                  FOREIGN KEY (Sno) REFERENCES student(Sno),            //在表级定义参照完整性//
                  FOREIGN KEY (Cno) REFERENCES course(Cno),             //在表级定义参照完整性//
                  );
 5.2.2  参照完整性检查和违约处理                 
 [例5.4]  显示说明参照完整性的违约处理示例。
          CREATE TABLE sc
                  (Sno CHAR(9),
                   Cno CHAR(4),
                   Grade SMALLINT,
                     PRIMARY KEY(Sno,Cno),
                     FOREIGN KEY(Sno) REFERENCES student(Sno)
                                ON DELETE CASCADE
                                         
                                          ON UPDATE CASCADE
                     FOREIGN KEY(Cno)REFERENCES course(Cno)
                                ON DELETE NO ACTION
                                         
                                          ON UPDATE CASCADE
                     );                         
 [例5.5] 在定义sc表时,说明Sno,Cno,Grade属性不允许取空值。
                 CREATE TABLE sc
                     (Sno CHAR(9) NOT NULL,
                          Cno CHAR(4) NOT NULL,
                          Grade SMALLINT NOT NULL,
                          PRIMARY KEY(Sno,Cno),
                                  .
                                          .
                                          .
                             );             
         
 [例5.6] 建立部门表DEPT,要求部门名称Nname列取值唯一,部门编号Deptno列为主码。
         CREATE TABLE DEPT
                      (Deptno NUMERIC(2),
                           Dname CHAR(9) UNIQUE NOT NULL,
                             Location CHAR(10),
                             PRIMARY KEY(Deptno)
                             );
 [例5.7] student表的Ssex只允许取"男"和"女"。
         CREATE TABLE student
                      (Sno CHAR(9) PRIMARY KEY,
                          Sname CHAR(8) NOT NULL,
                          Ssex CHAR(2) CHECK(CHECK(Ssex IN('男','女')),
                          
                          Sage SMALLINT,
                          Sdept CHAR(20)
                          );
 [例5.8] sc表的Grade的值应该在0和100之间。
         CREATE TABLE sc
                       (Sno CHAR(9),
                             Cno CHAR(4),
                             Grade SMALLINT CHECK(Grade>=0 AND Grade<=100),
                             PRIMARY KEY(Sno,Cno),
                             FOREIGN KEY(Sno)REFERENCES student(Sno),
                             FOREIGN KEY(Cno) REFERENCES course(Cno)
                             );
 [例5.9] 当学生的性别是男时,其名字不能以Ms.打头。
          CREATE TABLE student
                    (Sno CHAR(9),
                      Sname CAHR(8) NOT NULL,
                      Ssex CHAR(2),
                      Sage SMALLINT,
                      Sdept  CHAR(20),
                      PRIMARY KEY(Sno),
                      CHECK(Ssex='女' OR Sname NOT LIKE 'Ms.%')
                      );
                      
 [例5.10] 建立学生登记表student,要求学号在90000~99999之间,姓名不能取空值,年龄小于30,性别只能是"男"或"女"。
          CREATE TABLE student
                       (Sno NUMERIC(6)
                                  CONSTRAINT C1 CHECK(Sno BETWEEN 90000 AND 99999),
                              Sname CHAR(20)
                                      CONSTRAINT C2 NOT NULL,
                              Sage NUMERIC(3)
                                  CONSTRAINT C3 CHECK(Sage<30),
                              Ssex CHAR(2)
                                  CONSTRAINT C4 CHECK(Ssex IN('男','女')),
                                      CONSTRAINT studentKey PRIMARY KEY(Sno)
                             );
 [例5.11] 建立教师表TEACHER,要求每个教师的应发工资不低于3000元。
           应发工资是工资列Sal与扣除项Deduct之和。
                   CREATE TABLE TEACHER
                        (Eno NUMERIC(4) PRIMARY KEY,
                           Ename CHAR(10),
                             Job CHAR(8),
                             Sal NUMERIC(7,2),
                             Deduct NUMERIC(2),
                             CONSTRAINT TEACHERKey FOREIGN KEY(Deptno)
                              REFERENCES DEPT(Deptno),
                              CONSTRAINT C1 CHECK(Sal+Deduct>=3000)
                              );
 [例5.12] 去掉[例5.10] student表中对性别的限制。
           ALTER TABLE student
                           DROP CONSTRAINT C4; 
 [例5.13] 修改表student中的约束条件,要求学号改为在900000~999999之间,年龄由小于30改为小于40。
          ALTER TABLE student
                        DROP CONSTRAINT C1;
                ALTER TABLE student
                        ADD CONSTRAINT C1 CHECK(Sno BETWEEN 900000 AND 999999);
                  ALTER TABLE student
                        DROP CONSTRAINT C3;
                  ALTER TABLE student
                        ADD CONSTRAINT C3 CHECK(Sage<40);
 [例5.21] 当对表sc的Grade属性进行修改时,若分数增加了10%,则将此次操作记录到另一个表SC_U (Sno、Cno、Oldgrade、Newgrade)中,其中Oldgrade是修改前的分数,Newgrade是修改后的分数。
                  CREATE TRIGGER sc_T
                  AFTER UPDATE OF Grade ON sc
                  
                  REFEREBCING
                       OLDROW AS OldTuple,
                             NEWROW AS NewTuple
         FOR EACH ROW 
             WHEN(NewTuple.Grade>=1.1*OldTuple.Grade)
                  INSERT INTO sc_U(Sno,Cno,OldGrade,NewGrade)
                      VALUES(OLdTuple.Sno,OldTuple.Cno,OldTuple.Grade,NewTuple.Grade)            
 [例5.23] 定义一个BEFORE行级触发器,为教师表Teacher定义完整性规则“教授的工资不得低于4000元,如果低于4000元,自动改为4000元”。
           CREATE TRIGGER INSert_Or_Update_Sal
                     BEFORE INSERT OR UPDATE ON Teacher
                     REFERENCING  NEW row AS newTuple
                     FOR EACH ROW
                     BEGIN
                          IF(newtuple.Job='教授') AND (newtuple.Sal<4000)
                              
                                 THEN newtuple.Sal:=4000;
                                     END IF;
                     END;