数据库(SQL)之trigger(触发器)的使用以及视图(view)的基本实现

对于触发器,首先需要明确的是一下几点:
这里写图片描述

  1. trigger_name 必须给触发器命令,最多64个字符,建议用表的名字_触发器类型的缩写方法命名。如ttlsa_posts_bi(表ttlsa_posts,触发器发生在insert之前before)
  2. DEFINER子句 在激活触发器时,检查访问权限,确保触发器安全使用。
  3. trigger_time 定义触发器触发时间。可以设置为在行记录更改之前或之后发生。
  4. trigger_event 定义触发器触发事件。触发的事件有: INSERT:当一个新行插入到表中时触发。如INSERT、LOAD DATA和REPLACE语句。 UPDATE:当一个行数据被更改时触发。如UPDATE语句。 DELETE:当一个行从表中删除时触发。如DELETE和REPLACE语句。 注意:DROP TABLE和TRUNCATE TABLE语句不会触发该触发器,因为它们不是使用DELETE。同样删除一个分区表也不会触发。 有一个潜在的混乱情况,如INSERT INTO … ON DUPLICATE KEY UPDATE … 取决于是否有重复键行。 不能对一个表创建具有相同的触发事件和触发时间的多个触发器。如对于一个表不能创建两个BEFORE UPDATE触发器,但是,可以创建一个BEFORE UPDATE和一个BEFORE INSERT或一个BEFORE UPDATE和一个AFTER UPDATE触发器。
  5. FOR EACH ROW子句 定义触发执行间隔。FOR EACH ROW子句定义触发器每隔一行执行一次动作,而不是对整个表执行一次。
  6. trigger_body子句 包含要触发执行的SQL语句。可以是任何合法的语句,包括复合语句(需要使用BEGIN … END结构),流控制语句(if、case、while、loop、for、repeat、leave、iterate),变量声明(declare)以及指派(set),异常处理声明,允许条件声明,但是这里的语句受的限制和函数的一样。
  7. OLD与NEW 在触发器的SQL语句中,可以关联表中的任何列,通过使用OLD和NEW列名来标识,如OLD.col_name、NEW.col_name。OLD.col_name关联现有的行的一列在被更新或删除前的值。NEW.col_name关联一个新行的插入或更新现有的行的一列的值。 对于INSERT语句,只有NEW是合法的。否则会报错:ERROR 1363 (HY000): There is no OLD row in on INSERT trigger 对于DELETE语句,只有OLD是合法的。否则会报错:ERROR 1363 (HY000): There is no NEW row in on DELETE trigger 对于UPDATE语句,NEW和OLD可以同时使用。
代码中实现的功能:
  1. 订单号从1401开始自增长
  2. 更新订单同时可以更新GOODS表中的数据(通过触发器实现)一共定义了三个触发器,包括对ORDERS表进行增、删、改同时触发修改GOODS表中的数据
  3. 实现了使用视图查看具体信息

需要注意的问题:


  1. 数据库中的delimiter语句:简单说就是用于定义使用某个符号来结束语句,就像我们默认使用“;”来结束语句,当有时希望执行更多语句,比如定义触发器时,就需要重定义一个符号代替“;”,不需要的时候直接使用”declare ;“ 即可。
  2. 到底在什么时候修改表中内容的值?在很多情况下,如果需要修改当前表(触发后才更改的表认为是被触发表)的话,大多时候都是直接使用set new.属性语句,当然此时要使用before update/delete/insert,因为先set再更新就可以成功的修改数值了。

  3. 条件语句如何使用

if   then
(执行语句)
else
(执行语句)
end if

上代码:

DROP TABLE IF EXISTS GOODS;
DROP TABLE IF EXISTS ORDERS;

create table goods(
    id int,
    name char(10),
    price int,
    number int,
    primary key(id)
);


create table orders(
    order_id int auto_increment,
    good_id  int,
    number int,
    primary key(order_id)
)
auto_increment = 1401;

delimiter //
create trigger order_good
before insert on orders 
for each row
begin
    if new.number > 20 then
               update goods set goods.number=goods.number - 20 where 

new.good_id = goods.id;
               set new.number = '20';
        else
               update goods set goods.number=goods.number - 

new.number where new.good_id = goods.id;
        end if;
end
//

create trigger cancel_order
after delete on orders
for each row
begin
    update goods set goods.number = (goods.number + old.number) 

where goods.id = old.good_id;
end
//

create trigger change_order
before update on orders
for each row
begin
    if new.number > 20 then
             update goods set goods.number=(goods.number + old.number 

- 20) where new.good_id = goods.id;
             set new.number = 20;
        else
             update goods set goods.number=(goods.number + old.number 

- new.number) where new.good_id = goods.id;
        end if;
end

create trigger 
//
/*
INSERT INTO GOODS VALUES('1001', 'T-Shirt', '20', '1000');

INSERT INTO GOODS VALUES('1002', 'Mobile-pho', '1000', '20');

INSERT INTO GOODS VALUES('1003', 'Cup', '10', '800');

INSERT INTO ORDERS(GOOD_ID, NUMBER) VALUES('1001','100');
INSERT INTO ORDERS(GOOD_ID, NUMBER) VALUES('1002','10');
DELETE FROM ORDERS WHERE ORDERS.ORDER_ID = '1402';
UPDATE ORDERS SET ORDERS.NUMBER = 10 WHERE ORDERS.ORDER_ID = '1401';
*/

#创建视图:
create or replace view company(order_id, good_id, name, number)
as select orders.order_id, orders.good_id, goods.name, orders.number
from orders, goods
where orders.good_id = goods.id;
#展示视图:
select * from company;

create or replace view merchant(order_id,good_id, name, trade_amount)
as select orders.order_id, orders.good_id, goods.name, 

goods.price*orders.number
from orders, goods
where orders.good_id = goods.id;

实现效果:
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

关于触发器还可参考:

http://www.ttlsa.com/mysql/application-of-mysql-triggers/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值