![5d9c5210c9b0337ddc37608889420a4c.png](https://i-blog.csdnimg.cn/blog_migrate/e1bca1ec854e1a97a0455814f962ba2e.jpeg)
这篇是对前面一些知识的补缺补漏还有关于触发器
先写几个前提
![88bda264e2ecab3c647401963e9195ec.png](https://i-blog.csdnimg.cn/blog_migrate/ca42b0feab5aef2f639dc11babf86baf.png)
![17c10f6e2e95b002184b038c0296356b.png](https://i-blog.csdnimg.cn/blog_migrate/14d36a10b8e6ad086e95803128c516d0.png)
![70c944823e48767988716c368a3f6ec2.png](https://i-blog.csdnimg.cn/blog_migrate/aea16208884fcef237e9f73de2096c1a.png)
![4702e37f2fa8611fb8622dc39c9537e3.png](https://i-blog.csdnimg.cn/blog_migrate/a01d3388cb4ec1bf32b6869f41a9f079.png)
关于主键约束
违约拒绝执行
如何检查违约处理:
方法一:进行全表扫描 效率低
方法二:进行索引的建立,通过B+树进行检查。 效率高
外键约束:
建立两个表之间的联系,在本表该属性有的值,表2中的字段也有
(1)创建外键约束(这里时在初始化的时候建立)
foreign key(本表的字段名1,字段2,...) reference 表2的名称(表2中的主键字段,表3中的主键字段名,...)
表2中的字段必须是主键
![8eba61793ebc941077a8e3f2cfc8a897.png](https://i-blog.csdnimg.cn/blog_migrate/ea405adb238341fa58a9d263b12a1332.png)
破坏情况:
1.
![49d7740203b9f57d7033c0ea831b4bfc.png](https://i-blog.csdnimg.cn/blog_migrate/52d58a05bf754a5c8cc342005e60186d.jpeg)
2.
![eba6ec521d125df46f42908fc2058f29.png](https://i-blog.csdnimg.cn/blog_migrate/0ec4c3930cf1d09c0ac6ede09baf6f41.jpeg)
3.
![7678276bc99cfe75c83c658af2cf5b07.png](https://i-blog.csdnimg.cn/blog_migrate/9d8b0733032cf9a3f444b3c269f64734.jpeg)
4.
![72424f1b61b08001dc2551233552e2a1.png](https://i-blog.csdnimg.cn/blog_migrate/c28b0eab3c19b13975c35ffab8286ec1.jpeg)
违约处理方式:
![f38aaeb10ddd607f5df082158a5c845d.png](https://i-blog.csdnimg.cn/blog_migrate/a0e04e1a9249677d5540127a91155ed7.jpeg)
![c0c2b43daceec039803b00618cea23f0.png](https://i-blog.csdnimg.cn/blog_migrate/96e5652d95fabb761710f06a5f195655.jpeg)
![8e135cb39a3160e58950665b85b3c927.png](https://i-blog.csdnimg.cn/blog_migrate/1b38bfa8d231aae4fe0b854728d23219.jpeg)
(2)对于如何设置级联,拒绝,和设置为空值 只有外键约束拥有
在约束的定义后面加上
级联
on 操作(egg.delete) cascade
拒绝
on 操作 no action
设置为空
on 操作 set null
举个栗子:设置Student的Sno为SC表的外键约束,且为级联删除
![e3ef3bdcc1536d420a527bd5e68e2e30.png](https://i-blog.csdnimg.cn/blog_migrate/1782d1c4587fe144391357fbc13a99f5.png)
设置同时为级联删除和级联更新
在on delete cascade后面加一行on update cascade
其他约束:
1.叠加定义约束
egg:
unique not null
2.这里补充一个约束
定义属性值应该满足的条件
类型1.
初始化时添加
字段 类型, Check(字段 in(值1,值2..))
修改时添加
![ccccf7c49967af15a46c76687b2f3d26.png](https://i-blog.csdnimg.cn/blog_migrate/07724f7c10a27f512e7a0a6b9c9a2ae8.png)
字段 类型, Check(范围)
类型2.
初始表时放在字段声明后
check(条件)
一般来说第二种类型比较好
检查和违规处理
检查插入值是否满足,不满足则拒绝
为约束命名
Constraint 约束名 约束语句
删除约束
Alter table 表名
drop constraint 约束名
![cd5263222d657943f8e64fcc7c0e6790.png](https://i-blog.csdnimg.cn/blog_migrate/c6c163c9b261eb421bd1003d9a684dc7.png)
增加约束
alter table 表名
add constraint 约束名 约束定义
![0af5e575b0231b3a0b1333542cb527cc.png](https://i-blog.csdnimg.cn/blog_migrate/24683ffa89b6e1562cf477060ec47ead.png)
修改约束
先删除后增加
断言
反正我没有测试出来,而且mysql官方文档也没有查到assertion
对于多个表的限制条件
1.增加断言
check assertion 断言名
check(子句)
子句和where子句的格式类似
egg:
选修数据库的学生不能多于60
![f9149db9ec32c2fbb0fa47c3e01d4f21.png](https://i-blog.csdnimg.cn/blog_migrate/d50ee95ab69f832c093741ad79a21815.jpeg)
![a4e095c12dc2cfdabec4e2a449f6d6b9.png](https://i-blog.csdnimg.cn/blog_migrate/84aa09856babb066ff4d14bbe21470c5.jpeg)
2.删除断言
drop assertion 断言名
触发器
在某事件发生的时候触发
1.定义触发器
create trigger 触发器名
before|after 触发事件 on 表名
referencing new|old row|table as 变量 解释:将这行|表的旧|新的命名为变量名
for each row|statement
[when 触发条件] 触发动作体
如果省略[when 触发条件]则触发动作体在触发器激活后立即执行
row 行级触发器
statement 语句级触发器
如果是行级触发器,用户可以在过程体中使用new和old引用事件之后的新值和事件之前的旧值,如果时语句级触发器,则不能在触发动作体中使用new或old进行引用
上面是我书上看来的。。。然而用不了
下面是一般用法
create trigger 触发器名
after|before insert|update|delete
on 表名
for each row
begin
SQL语句; 这里是触发程序
end;
before:在执行触发事件之前触发
after:在执行触发事件之后触发
如果触发动作执行失败,激活触发器事件就会终止执行,触发器的目标表或触发器可能影响的其他对象不发生任何变化
注意:触发器名和表名要在同一模式下
old表示旧记录,new表示新记录
对于INSERT语句,只有NEW是合法的;对于DELETE语句,只有OLD才合法;而UPDATE语句可以在和NEW以及OLD同时使用。
old是只读的,在触发程序中只能引用它,不能更改它。在before触发程序中。可以使用“set new.字段名=值”更改new记录的值。但是在after触发程序中不能使用“set new.字段名=值”更改记录的值。
![44ab082193e44cd663f893908680ca16.png](https://i-blog.csdnimg.cn/blog_migrate/b33b397d8b650b847f4518a440e2e230.png)
标准8.0文档
egg:
![716d2b45952693eae40ee7c3016a5a22.png](https://i-blog.csdnimg.cn/blog_migrate/099c67469417c21bdb7ed9642e1d8582.jpeg)
举个栗子1:下面的是行不通的
![fb2845009546d09e8808182725975321.png](https://i-blog.csdnimg.cn/blog_migrate/24d489dec00d7a49037d7a5c92da1402.jpeg)
![e7cac75b9f1596fa89f514d152bb4188.png](https://i-blog.csdnimg.cn/blog_migrate/34e95d0694064902c5f3508283c3088d.png)
栗子2.
![913878778a5c16fea4309d410294fd7e.png](https://i-blog.csdnimg.cn/blog_migrate/509545fd0782587e4c369422170dd76e.jpeg)
![6eb0d5b0ad0a16fa166a48640ed313d6.png](https://i-blog.csdnimg.cn/blog_migrate/4f49bcc6955a5ea623c0d19eae6a3036.jpeg)
2.激活触发器
(1)触发器的执行时有触发事件激活的,并有数据库服务器自动执行
(2)一个数据表上可能定义了多个触发器,遵循下列执行顺序
执行该表上的before触发器
激活触发器的sql
执行该表上的after触发器
3.删除触发器
drop trigger 触发器名 on 表名
上面语句也不行。。。
![3440bf96a14ba5c091745a55f13ccef4.png](https://i-blog.csdnimg.cn/blog_migrate/7a9984b7d3c226da9d8512f4f52b199f.png)
我这里改了一下结束符
![e48631a0734a8c900a86faa8b53c9cb2.png](https://i-blog.csdnimg.cn/blog_migrate/1ab4d16ac664f0eadc55951b85d02b05.png)
触发器可以用来设置级联操作
查看触发器的定义
1.
show trigger like 模式 G
上面的中模式 eg:
”stu%“ 表示查找触发器所在表的名称的前几个字符为stu
2.
show create trigger 触发器名
查看指定触发器名的定义
3.
select * from information_schema.triggerG
由于mysql的所有触发器的定义都存放在information_schema数据库的trigger表中,所以查看所有触发器的详细信息可以像上面一样。
我也是挺无语的,这课上的和实际的挺多不一样的。。。。