1. 程式人生 > >資料庫(SQL)之trigger(觸發器)的使用以及檢視(view)的基本實現

資料庫(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;

實現效果:
這裡寫圖片描述
這裡寫圖片描述
這裡寫圖片描述
這裡寫圖片描述
這裡寫圖片描述
這裡寫圖片描述

關於觸發器還可參考: