1、視圖python
視圖是一個虛擬表(非真實存在),其本質是【根據SQL語句獲取動態的數據集,併爲其命名】,用戶使用時只需使用【名稱】便可獲取結果集,能夠將該結果集當作表來使用。mysql
使用視圖咱們能夠把查詢過程當中的臨時表摘出來,用視圖去實現,這樣之後再想操做該臨時表的數據時就無需重寫複雜的sql了,直接去視圖中查找便可,但視圖有明顯地效率問題,而且視圖是存放在數據庫中的,若是咱們程序中使用的sql過度依賴數據庫中的視圖,即強耦合,那就意味着擴展sql極爲不便,所以並不推薦使用程序員
一、建立視圖sql
語法:CREATE VIEW 視圖名稱 AS SQL語句數據庫
create view teacher_view as select tid from teacher where tname='李平老師';網絡
!!!注意注意注意:ide
1)使用視圖之後就無需每次都重寫子查詢的sql,可是這麼效率並不高,還不如咱們寫子查詢的效率高函數
2)並且有一個致命的問題:視圖是存放到數據庫裏的,若是咱們程序中的sql過度依賴於數據庫中存放的視圖,那麼意味着,一旦sql須要修改且涉及到視圖的部分,則必須去數據庫中進行修改,而一般在公司中數據庫有專門的DBA負責,你要想完成修改,必須付出大量的溝通成本DBA可能纔會幫你完成修改,極其地不方便。oop
二、使用視圖fetch
修改視圖,原始表也跟着改
create view course_view as select * from course; #建立表course的視圖
select * from course_view;
update course_view set cname='xxx'; #更新視圖中的數據
insert into course_view values(5,'yyy',2); #往視圖中插入數據
select * from course; #發現原始表的記錄也跟着修改了
注:通常狀況下不該該修改視圖中的記錄,並且在涉及多個表的狀況下是根本沒法修改視圖中的記錄
三、修改視圖
語法:ALTER VIEW 視圖名稱 AS SQL語句 (alter 變動)
alter view teacher_view as select * from course where cid>3;
四、刪除視圖
語法:DROP VIEW 視圖名稱
DROP VIEW teacher_view
2、觸發器
使用觸發器能夠定製用戶對錶進行【增、刪、改】操做時先後的行爲。注意:沒有查詢!!!
一、建立觸發器
插入前
CREATE TRIGGER tri_before_insert_tb1 BEFORE INSERT ON tb1 FOR EACH ROW
BEGIN
...
END
插入後
CREATE TRIGGER tri_after_insert_tb1 AFTER INSERT ON tb1 FOR EACH ROW
BEGIN
...
END
刪除前
CREATE TRIGGER tri_before_delete_tb1 BEFORE DELETE ON tb1 FOR EACH ROW
BEGIN
...
END
刪除後
CREATE TRIGGER tri_after_delete_tb1 AFTER DELETE ON tb1 FOR EACH ROW
BEGIN
...
END
更新前
CREATE TRIGGER tri_before_update_tb1 BEFORE UPDATE ON tb1 FOR EACH ROW
BEGIN
...
END
更新後
CREATE TRIGGER tri_after_update_tb1 AFTER UPDATE ON tb1 FOR EACH ROW
BEGIN
...
END
舉個栗子:
CREATE TRIGGER tri_after_insert_cmd AFTER INSERT ON cmd FOR EACH ROW
BEGIN
IF NEW.success = 'no' THEN #等值判斷只有一個等號
INSERT INTO errlog(err_cmd, err_time) VALUES(NEW.cmd, NEW.sub_time) ; #必須加分號
END IF ; #必須加分號
END
特別的:NEW表示即將插入的數據行,OLD表示即將刪除的數據行。
二、使用觸發器
觸發器沒法由用戶直接調用,而知因爲對錶的【增/刪/改】操做被動引起的。
三、刪除觸發器
drop trigger tri_after_insert_cmd;
3、事務
事務用於將某些操做的多個SQL做爲原子性操做,一旦有某一個出現錯誤,便可回滾到原來的狀態,從而保證數據庫數據完整性。
create table user(
id int primary key auto_increment,
name char(32),
balance int
);
insert into user(name,balance)
values
('wsb',1000),
('egon',1000),
('ysb',1000);
#原子操做
start transaction;
update user set balance=900 where name='wsb'; #買支付100元
update user set balance=1010 where name='egon'; #中介拿走10元
update user set balance=1090 where name='ysb'; #賣家拿到90元
commit;
#出現異常,回滾到初始狀態
start transaction;
update user set balance=900 where name='wsb'; #買支付100元
update user set balance=1010 where name='egon'; #中介拿走10元
uppdate user set balance=1090 where name='ysb'; #賣家拿到90元,出現異常沒有拿到
rollback;
commit;
mysql> select * from user;
+----+------+---------+
| id | name | balance |
+----+------+---------+
| 1 | wsb | 1000 |
| 2 | egon | 1000 |
| 3 | ysb | 1000 |
+----+------+---------+
4、存儲過程
一、介紹
存儲過程包含了一系列可執行的sql語句,存儲過程存放於MySQL中,經過調用它的名字能夠執行其內部的一堆sql
使用存儲過程的優勢:
1)用於替代程序寫的SQL語句,實現程序與sql解耦
2)基於網絡傳輸,傳別名的數據量小,而直接傳sql數據量大
使用存儲過程的缺點:
1)程序員擴展功能不方便
補充:程序與數據庫結合使用的三種方式
方式一:
MySQL:存儲過程
程序:調用存儲過程
方式二:
MySQL:
程序:純SQL語句
方式三:
MySQL:
程序:類和對象,即ORM(本質仍是純SQL語句)
二、建立簡單存儲過程(無參)
delimiter //
create procedure p1()
BEGIN
select * from blog;
INSERT into blog(name,sub_time) values("xxx",now());
END //
delimiter ;
在mysql中調用: call p1()
在python中基於pymysql調用
cursor.callproc('p1')
print(cursor.fetchall())
三、建立存儲過程(有參)
對於存儲過程,能夠接收參數,其參數有三類:
in 僅用於傳入參數用
out 僅用於返回值用
inout 既能夠傳入又能夠看成返回值
四、執行存儲過程
-- 無參數:call proc_name()
-- 有參數,全in:call proc_name(1,2)
-- 有參數,有in,out,inout
set @t1=0;
set @t2=3;
call proc_name(1,2,@t1,@t2)
五、刪除存儲過程
drop procedure proc_name;
五 函數
MySQL中提供了許多內置函數
一、自定義函數
注意:函數中不要寫sql語句(不然會報錯),函數僅僅只是一個功能,是一個在sql中被應用的功能
若要想在begin...end...中寫sql,請用存儲過程
二、刪除函數
三、執行函數
6、流程控制
一、條件語句
if條件語句
delimiter //
CREATE PROCEDURE proc_if ()
BEGIN
declare i int default 0;
if i = 1 THEN
SELECT 1;
ELSEIF i = 2 THEN
SELECT 2;
ELSE
SELECT 7;
END IF;
END //
delimiter ;
二、循環語句
while循環
delimiter //
CREATE PROCEDURE proc_while ()
BEGIN
DECLARE num INT ;
SET num = 0 ;
WHILE num < 10 DO
SELECT
num ;
SET num = num + 1 ;
END WHILE ;
END //
delimiter ;
repeat循環
delimiter //
CREATE PROCEDURE proc_repeat ()
BEGIN
DECLARE i INT ;
SET i = 0 ;
repeat
select i;
set i = i + 1;
until i >= 5
end repeat;
END //
delimiter ;
loop
BEGIN
declare i int default 0;
loop_label: loop
set i=i+1;
if i<8 then
iterate loop_label;
end if;
if i>=10 then
leave loop_label;
end if;
select i;
end loop loop_label;
END