天天看點

MySQL-SQL存儲函數以及觸發器詳解

作者:二進制狂人kxyL

MySQL

MySQL是一個關系型資料庫管理系統,由瑞典MySQL AB 公司開發,屬于 Oracle 旗下産品。MySQL 是最流行的關系型資料庫管理系統之一,在 WEB 應用方面,MySQL是最好的 RDBMS (Relational Database Management System,關系資料庫管理系統) 應用軟體之一。MySQL是一種關系型資料庫管理系統,關系資料庫将資料儲存在不同的表中,而不是将所有資料放在一個大倉庫内,這樣就增加了速度并提高了靈活性。MySQL所使用的 SQL 語言是用于通路資料庫的最常用标準化語言。MySQL 軟體采用了雙授權政策,分為社群版和商業版,由于其體積小、速度快、總體擁有成本低,尤其是開放源碼這一特點,一般中小型和大型網站的開發都選擇 MySQL 作為網站資料庫。

SQL

結構化查詢語言(Structured Query Language)簡稱SQL,是一種特殊目的的程式設計語言,是一種資料庫查詢和程式設計語言,用于存取資料以及查詢、更新和管理關系資料庫系統。結構化查詢語言是進階的非過程化程式設計語言,允許使用者在高層資料結構上工作。它不要求使用者指定對資料的存放方法,也不需要使用者了解具體的資料存放方式,是以具有完全不同底層結構的不同資料庫系統, 可以使用相同的結構化查詢語言作為資料輸入與管理的接口。結構化查詢語言語句可以嵌套,這使它具有極大的靈活性和強大的功能。

存儲函數

1). 介紹

存儲函數是有傳回值的存儲過程,存儲函數的參數隻能是 IN 類型的。具體文法如下:

CREATE FUNCTION 存儲函數名稱 ([ 參數清單 ])

RETURNS type [characteristic ...]

BEGIN

-- SQL語句

RETURN ...;

END ;

characteristic 說明

DETERMINISTIC :相同的輸入參數總是産生相同的結果

NO SQL :不包含 SQL 語句。

READS SQL DATA :包含讀取資料的語句,但不包含寫入資料的語句。

2). 案例

計算從 1 累加到 n 的值, n 為傳入的參數值。

create function fun1(n int)

returns int deterministic

begin

declare total int default 0;

while n>0 do

set total := total + n;

set n := n - 1;

end while;

return total;

end;

select fun1(50);

在 mysql8.0 版本中 binlog 預設是開啟的,一旦開啟了, mysql 就要求在定義存儲過程時,需要指定

characteristic 特性,否則就會報如下錯誤:

觸發器

介紹

觸發器是與表有關的資料庫對象,指在 insert/update/delete 之前 (BEFORE) 或之後 (AFTER) ,觸

發并執行觸發器中定義的 SQL 語句集合。觸發器的這種特性可以協助應用在資料庫端確定資料的完整性, 日志記錄 , 資料校驗等操作 。

使用别名 OLD 和 NEW 來引用觸發器中發生變化的記錄内容,這與其他的資料庫是相似的。現在觸發器還隻支援行級觸發,不支援語句級觸發。

文法

1). 建立

CREATE TRIGGER trigger_name

BEFORE/AFTER INSERT/UPDATE/DELETE

ON tbl_name FOR EACH ROW -- 行級觸發器

BEGIN

trigger_stmt ;

END;

2). 檢視

SHOW TRIGGERS ;

3). 删除

DROP TRIGGER [schema_name.]trigger_name ; -- 如果沒有指定 schema_name,預設為目前數

據庫 。

案例

通過觸發器記錄 tb_user 表的資料變更日志,将變更日志插入到日志表 user_logs 中 , 包含增加 ,

修改 , 删除 ;

表結構準備 :

-- 準備工作 : 日志表 user_logs

create table user_logs(

id int(11) not null auto_increment,

operation varchar(20) not null comment '操作類型, insert/update/delete',

operate_time datetime not null comment '操作時間',

operate_id int(11) not null comment '操作的ID',

operate_params varchar(500) comment '操作參數',

primary key(`id`)

)engine=innodb default charset=utf8;

A. 插入資料觸發器

create trigger tb_user_insert_trigger

after insert on tb_user for each row

begin

insert into user_logs(id, operation, operate_time, operate_id, operate_params)

VALUES

(null, 'insert', now(), new.id, concat('插入的資料内容為:

id=',new.id,',name=',new.name, ', phone=', NEW.phone, ', email=', NEW.email, ',

profession=', NEW.profession));

end;

測試:

-- 檢視

show triggers ;

-- 插入資料到tb_user

insert into tb_user(id, name, phone, email, profession, age, gender, status,

createtime) VALUES (26,'三皇子','18809091212','[email protected]','軟體工

程',23,'1','1',now());

測試完畢之後,檢查日志表中的資料是否可以正常插入,以及插入資料的正确性。

B. 修改資料觸發器

create trigger tb_user_update_trigger

after update on tb_user for each row

begin

insert into user_logs(id, operation, operate_time, operate_id, operate_params)

VALUES

(null, 'update', now(), new.id,

concat('更新之前的資料: id=',old.id,',name=',old.name, ', phone=',

old.phone, ', email=', old.email, ', profession=', old.profession,

' | 更新之後的資料: id=',new.id,',name=',new.name, ', phone=',

NEW.phone, ', email=', NEW.email, ', profession=', NEW.profession));

end;

測試:

-- 檢視

show triggers ;

-- 更新

update tb_user set profession = '會計' where id = 23;

update tb_user set profession = '會計' where id <= 5;

測試完畢之後,檢查日志表中的資料是否可以正常插入,以及插入資料的正确性。

C. 删除資料觸發器

create trigger tb_user_delete_trigger

after delete on tb_user for each row

begin

insert into user_logs(id, operation, operate_time, operate_id, operate_params)

VALUES

(null, 'delete', now(), old.id,

concat('删除之前的資料: id=',old.id,',name=',old.name, ', phone=',

old.phone, ', email=', old.email, ', profession=', old.profession));

end;

測試:

-- 檢視

show triggers ;

-- 删除資料

delete from tb_user where id = 26;

測試完畢之後,檢查日志表中的資料是否可以正常插入,以及插入資料的正确性。

繼續閱讀