zoukankan      html  css  js  c++  java
  • 【SQL】约束与触发器2

    3.修改约束

    3.1给约束命名

    按如下格式命名:

    name CHAR(30) CONSTRAINT NameIsKey PRIMARY KEY
    gender CHAR(1) CONSTRAINT NoAndro
                                CHECK (gender IN ('F','M'))
    CONSTRAINT RightTitle
        CHECK (gender = 'F' or name NOT LIKE 'Ms.%')

    3.2 修改表上的约束

    ①修改约束的检查时间

    SET CONSTRAINT MyConstraint DEFERRED;

    SET CONSTRAINT MyConstraint IMMEDIATE;

    ②用ALTER TABLE语句

    删除约束 DROP

    ALTER TABLE MovieStar DROP CONSTRAINT NameIsKey;
    ALTER TABLE MovieStar DROP CONSTRAINT NoAndro;
    ALTER TABLE MovieStar DROP CONSTRAINT RightTitle;

    添加约束 ADD(注意,约束必须是要整个表遵守时才加)

    ALTER TABLE MovieStar ADD CONSTRAINT NameIsKey
        PRIMARY KEY(name);
    ALTER TABLE MovieStar ADD CONSTRAINT NoAndro
        CHECK (gender IN ('F','M'));
    ALTER TABLE MovieStar ADD CONSTRAINT RightTitle
        CHECK (gender = 'F' OR name NOT LIKE 'Ms.%');

    注意:SQL不会记住已经删除的约束,所以如果要添加之前删除的约束必须重新写一遍。

     

     四、断言

    1.创建断言

    CREATE ASSERTION 断言名 CHECK (条件)

    2.使用断言

    CREATE ASSERTION RichPres CHECK
        (NOT EXISTS
            (SELECT Studio.name
             FROM Studio, MovieExec
             WHERE presC# = cert# AND netWorth < 1000000
            )
        );

    上面的断言不允许资金小于1000000的经理。

    CREATE ASSERTION SumLength CHECK (10000 >= ALL
        (SELECT SUM(length) FROM Movies GROUP BY studioName)
    );

    上面的断言不允许电影公司的电影总长度超过10000分钟。

    如果这个语句用CHECK约束写,是

    CHECK ( 10000 >= ALL
        (SELECT SUM(length) FROM Movies GROUP BY studioName));

    断言和CHECK的区别:

    CHECK只在插入和修改时有效,但对删除不做检查,在有些情况下会导致约束不成立。

    断言则在任何提及的关系改变时都会检查,确保条件成立。

    3.删除断言

    DROP ASSERTION 断言名

    五、触发器

    当特定事件发生时,触发器被激活。如果状态满足触发器中的条件,则该触发器相连的动作被执行。

    例子:

    1.不允许降低电影制作人的净资产

    CREATE TRIGGER NetWorthTrigger
    AFTER UPDATE OF netWorth ON MovieExec
    REFERENCING
        OLD ROW AS OldTuple,
        NEW ROW AS NewTuple
    FOR EACH ROW
    WHEN (OldTuple.netWorth > NewTuple.netWorth)
        UPDATE MovieExec
        SET netWorth = OldTuple.netWorth
        WHERE cert# = NewTuple.cert#;

    2.阻止电影制作人的平均资产降到500000.要对插入、删除、修改分别设置触发器。这里列出修改的:

    CREATE TRIGGER AvgNetWorthTrigger
    AFTER UPDATE OF netWorth ON MovieExec
    REFERENCING
        OLD TABLE AS OldStuff,
        NEW TABLE AS NewStuff
    FOR EACH STATEMENT
    WHEN (500000 > (SELECT AVG(netWorth) FROM MovieExec))
    BEGIN
        DELETE FROM MovieExec
        WHERE (name, address, cert#, netWorth) IN NewStuff;
        INSERT INTO MovieExec
            (SELECT * FROM OldStuff);
    END;

    3.以year为主键的一部分,防止主键为空。在插入前如果发现year为空则插入默认值1915

    CREATE TRIGGER FixYearTrigger
    BEFORE INSERT ON Movies
    REFERENCING
        NEW ROW AS NewRow
        NEW TABLE AS NewStuff
    FOR EACH ROW
    WHEN NewRow.year IS NULL
    UPDATE NewStuff SET year = 1915;

    相关选项介绍:

    AFTER/BEFORE:决定测试是在事件发生前还是发生后

    可被触发的事件:UPDATEINSERTDELETE

    OF 属性:UPDATE的可选项,如果选中,则只有列出的属性变化时才激活触发器。

    WHEN语句:可选项,如果选择,则条件为真才执行后面的语句,否则一定执行后面的语句。

    多个执行动作:用BEGIN, END括起来

    OLD ROW AS/NEW ROW AS/OLD TABLE AS/NEW TABLE AS:引用表修改前后的元组和表

    FOR EACH ROW/FOR EACH STATEMENT:行级触发器,语句级触发器。如果更新整个表,行级触发器要对修改的元组一次一个的执行;语句级触发器则只用执行一次。语句级触发器不能引用新旧元组,但可以引用新旧表;行级触发器则都可以引用。

    插入元组则没有旧值,删除元组则没有新值

     

  • 相关阅读:
    Unity3d资源管理分析
    Unity3D之MonoBehaviour的可重写函数整理
    Unity3D脚本学习——运行时类
    A*寻路初探(转载)
    360sdk网游支付服务
    总结使用Unity 3D优化游戏运行性能的经验
    Unity3D之Lightmap详解
    「luogu2714」四元组统计
    「BZOJ1066」[SCOI2007]蜥蜴
    「luogu1251」餐巾计划问题
  • 原文地址:https://www.cnblogs.com/dplearning/p/4883515.html
Copyright © 2011-2022 走看看