数据库系统概率-小测1-实验8

数据库检测!!!
一般我们触发器是这样写的。

DELIMITER %% 
create trigger insertorder
before insert on OrderDetails
for each row
begin
	update Products set UnitsInStock = UnitsInStock -  new.Quantity where 	  ProductID = 	new.ProductID;
end
%%DELIMITER;


delimiter%%
create trigger prod_ins
before insert on Products
for each row
begin
	if new. UnitPrice <=0 or new.UnitPrice>=100 
	then
	signal sqlstate '45000'
	set message_text = '不能插入数据,单价只能是大于0小于100';
	end if;
end;
%%delimiter;

1、什么是触发器?
事件-条件-动作。
当发生增删改查(事件)时,对条件进行扫描,符合就执行动作,不符合就不执行。

2、如何定义触发器?
create trigger 触发器名
before/after 触发事件 on 表名 指明触发器激活的时间是在执行触发事件倩还是后
referencing new/old row as 变量名 referencing指出你要引用的变量
for each row/statement 定义触发器的类型,指明触发器的执行频率
when 触发条件 触发动作体

3、触发器是数据库的什么性?为什么?

4、触发器和约束的区别在哪里?
触发器类似于约束,但是比约束要强大的多。
因为它可以进行更加复杂的操作。

5、触发器只能定义在哪里?那个地方叫什么?
只能定义在基本表上,不能定义在视图上。
基本表也叫目标表。

6、触发事件可以是什么?
单个insert、update、delete
多个的组合 insert or update ,这个就是强大之处。
update of 触发列 这个的意思是什么?
修改哪些列的时候,就激活触发器。

7、after/before表示什么?
表示触发的时机。
a,在触发事件(insert、update、delete)执行之后,激活触发器
b,之前,激活触发器

8、for each row 和 statement 什么意思?
触发器动作间隔,行级和语句级触发器。

9、如果update teacher set num = 5;假设teacher表有100行。
如果是语级,就是执行完触发事件之后,激活触发器,动作执行体执行一次。
如果是行级,就是执行完触发事件之后,激活触发器,动作执行体执行100次。
什么时候,使用哪个???

10、触发条件when 有什么用?
如果写了when。
触发器被激活,只有触发条件为真,动作执行体执行才会执行。
否则不执行。
如果没有写when。
触发器被激活后,就执行触发器。

11、触发动作体,会怎么样?里面有什么需要注意的吗?
有可能失败,失败就停止执行,目标表或受影响的对象不变。
如果是行级row,用户可以引用new和old,
就是update或insert事件之前的新值和事件之后的后值。
如果是语句级,则不能在动作执行体中引用new和old。

12、5.21
我的答案:
create trigger trigger1
after update
分数 set = 1.1
on SC_U
referencing newgrade = 1.1 * oldgrade
for each row
newgrade = 1.1 * oldgrade;

书上答案
create trigger SC_T
after update of grade on SC
referencing
oldrow as oldtuple//元组
newrow as newtuple
for each row 触发事件,每grade更新之后,激活触发器,下面的规则(when就执行一次
when (newtuple.grade>oldtuple.grade*1.1)
insert into SC_U(Sno、Cno、 Oldgrade、 Newgrade)
values(oldtuple.Sno,oldtuple.Cno,oldtuple.grade,newtuple.grade);

13、若没有for each row,而是for each statement的话,
可以引用newtable,oldtable。

14、5.22 如果说是每次,有可能就是用触发器了。
我的答案:
create trigger t1
after insert on Student
referencing
oldrow as oldtuple//元组
newrow as newtuple
for each row
insert into

create trigger Student_Count
after insert on Student
referencing
newtable as delta
for each statement
insert into StudentInsertLog(numbers)
select count(*) from delta;

15、我们默认的触发器是?
语句触发器

16、delta是什么?
是关系名,模式和Student相同,包含的元组是insert语句增加的元组。

17、什么是PL/SQL过程块?
在动作执行体里面有begin和end
create trigger t1
before insert or update on teacher
referencing
new row as newtuple
for each row
begin
if(newtuple.job = jiaoshou) and (newtuple.sal<4000)
then newtuple:=4000
end if;
end;

18、数据库是如何激活触发器的呢?
一个数据表可以有几个触发器呢?那它们的执行顺序是什么呢?
触发器是由触发事件激活,数据库服务器执行。
一个表可以有多个触发器。
先before,多个before则看谁先创建
后sql语句
后after语句

19、如何删除数据库?
drop trigger 触发器名 on 表;

20、如何展示你已经创建的触发器?
show create trigger 触发器名;
show trigger;

实验8问题:
1、创建更新级联触发器 orderd_upd
delimiter%% /* DELIMITER为定义某个符号为命令结束符,此处用"%%" 代替";" 作为命令结束符 /
create trigger orderd_upd
after update on Orders
for each row
begin
update Orderdetails set OrderID = new.OrderID
where OrderID = old.OrderID;/
此处的";" 不再是命令结束符 /
end%%
delimiter;/
恢复";" 为命令行结束符 */

2、创建删除
delimiter%%
create trigger t1
after delete on Orders
for each row
begin
delete from OrderDetails where OrderID=old.OrderID;
end%%
delimiter;

3、产品表Products 中,规定单价UnitPrice的范围是大于0,
小于100,设计触发器prod_ins实现该约束。不在范围给出提示。
delimiter%%
create trigger prod_ins
before insert on Products
for each row
begin
if new. UnitPrice <=0 or new.UnitPrice>=100
then
signal sqlstate ‘45000’
set message_text = ‘不能插入数据,单价只能是大于0小于100’;
end if;
end;
%%delimiter;

4、为什么需要delimiter?
因为默认情况下delimiter是;号
在mysql中,遇到;就执行了,
有时候我们并不想这么做,所以
delimiter%%
%%delimiter;
这样他就会扫描完,delimiter内的东西,然再去执行。
如果不用的话,有可能报错。

5、
订购业务逻辑,包含下列3步,(请回顾实验5 数据库更新、插入、删除实验的综合实验)
第1步:在订单orders中添加一条新纪录:
订单号,雇员ID,订购日期,到货日期,发货日期,运货商,运货费等信息
第2步:在订单细节Orderdetails表中添加订购产品的相关记录
第3步:更新修改产品表中相关产品的库存量(减去订购的数量)
在实验5中,每一步都需要手工操作,但是很容易忘记第3步的操作(忘记更新库存,酿成大错),通过触发器自动实现第3步操作,效率高,不会犯错。
在OrderDetails 表上设计一个插入触发器,自动实现第3步的更新库存的操作。
DELIMITER %%
create trigger insertorder
before insert on OrderDetails
for each row
begin
update Products set UnitsInStock = UnitsInStock - new.Quantity where ProductID = new.ProductID;
end
%%DELIMITER;

6、在Orders上建立删除触发器 -实现级联删除!

DELIMITER %%
Create trigger deletcscd
after delete on Orders
for each row
begin
delete from OrderDetails where OrderID=old.OrderID;
end %%
//将在OrderDetails 中触发删除触发器
DELIMITER ;

特别要注意触发器串联:
在Orders删除触发级联删除触发器deletcscd, 而deletcscd 触发器将进一步触发deletorder
deletcscd -> deletorder
这里发生了级联删除。

知识补充:
1、
对于INSERT语句, 只有NEW是合法的;

对于DELETE语句,只有OLD才合法;

对于UPDATE语句,NEW、OLD可以同时使用。

2、mysql不支持语句触发器,所以必须写foreachrow;

3、for each row是数据库表的行还是sql语句的行?
指的是数据库表的行

4、for each row 触发器中的这个是什么意思 是不是必不可少 每个触发器都必须有?
一般都是做行级触发所以这么写 但不是必须的 for each row 就代表每行都相应XXX事件(insert update delete) 理解成每当往表插入(更新 删除)一行的时候就触发

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值