Python-視圖 觸發器 事務 存儲過程
阿新 • • 發佈:2018-11-27
utf 路徑 回滾事務 seve 優點 form 會有 執行 開始
1.視圖
2.觸發器***
在某個時間發生了某個事件時 會自動觸發一段sql語句
3.事務*****
是邏輯上的一組sql語句 他們要麽都成功 要麽都失敗 今後只要執行sql就會有事務
使用事務
start transaction; --開啟事物,在這條語句之後的sql將處在同一事務,並不會立即修改數據庫
commit;--提交事務,讓這個事物中的sql立即執行數據的操作,
rollback;--回滾事務,取消這個事物,這個事物不會對數據庫中的數據產生任何影響
四個特性
原子性:事務是一組不可分割的單位,要麽同時成功,要麽同時不成功
一致性:? 事物前後的數據完整性應該保持一致
隔離性:多個用戶並發訪問數據時,一個用戶的事物不能被其它用戶的事務所幹擾,多個並發事務之間數據要相互隔離
持久性:一個事物一旦被提交,它對數據的改變就是永久性的,接下來即使數據庫發生故障也不應該對其有任何影響
四個隔離級別
讀未提交:read uncommitted --不做任何隔離,可能臟讀,幻讀
讀已提交:read committed----可以防止臟讀,不能防止不可重復讀,和幻讀,
可重復讀:Repeatable read --可以防止臟讀,不可重復讀,不能防止幻讀
序列化執行(串行):Serializable--數據庫運行在串行化實現,所有問題都沒有,就是性能低
修改隔離級別:
select @@tx_isolation;--查詢當前級別
set[session|global] transaction isolation level .... ;修改級別
實例:
set global transaction isolation level Repeatable read ;
pymysql事務測試
import pymysql
conn = pymysql.connect(
user="root",
password="root",
database="day48",
charset="utf8"
)
cursor = conn.cursor(pymysql.cursors.DictCursor)
# cursor.execute("delete from account where id =1")
# conn.commit()
sql = "update account set money = money - 100 where id = 2"
sq2 = "update account set moneys = money + 100 where id = 3"
try:
cursor.execute(sql)
cursor.execute(sq2)
conn.commit()
print("提交了!")
except:
print("回滾了!")
conn.rollback()
# 把你需要放在同一事務的sql執行 放在try中 最後加上commit
# 如果捕獲到異常則執行rollback
4.存儲過程*****
是一堆sql語句的集合,相當於一個py的函數
優點:
應用程序開發者,工作量降低,
提高程序的執行效率 因為網絡io減少了
缺點:學習成本高,擴展性 維護性差
部門間溝通成本
pymysql調用存儲過程
import pymysql
conn = pymysql.connect(
user="root",
password="root",
database="day48",
charset="utf8"
)
cursor = conn.cursor(pymysql.cursors.DictCursor)
cursor.callproc("p1",(2,5,1)) #pymysql 會給參數全都創建對應的變量
# 命名方式 @_p1_0 @_p1_1 @_p1_2
print(cursor.fetchall()) # 如果過程中包含多個查詢語句 得到的是第一條查詢語句的結果
cursor.execute("select @_p1_2")
print(cursor.fetchone())
5.函數
6.備份與恢復***
mysqldump -u -p (庫名 [表名] | --all--databases --databases 庫名1 庫名2) > 文件路徑
恢復
1.mysql -u -p < 文件路徑
2.source 文件路徑
7.流程控制
----------------
1. 視圖
100個SQL:
88: v1
select .. from v1
select asd from v1
某個查詢語句設置別名,日後方便使用
- 創建
create view 視圖名稱 as SQL
PS: 虛擬
- 修改
alter view 視圖名稱 as SQL
- 刪除
drop view 視圖名稱;
2. 觸發器
當對某張表做:增刪改操作時,可以使用觸發器自定義關聯行為
insert into tb (....)
-- delimiter //
-- create trigger t1 BEFORE INSERT on student for EACH ROW
-- BEGIN
-- INSERT into teacher(tname) values(NEW.sname);
-- INSERT into teacher(tname) values(NEW.sname);
-- INSERT into teacher(tname) values(NEW.sname);
-- INSERT into teacher(tname) values(NEW.sname);
-- END //
-- delimiter ;
--
-- insert into student(gender,class_id,sname) values(‘女‘,1,‘陳濤‘),(‘女‘,1,‘張根‘);
-- NEW,代指新數據
-- OLD,代指老數據
3. 函數
def f1(a1,a2):
return a1 + a2
f1()
bin()
內置函數:
執行函數 select CURDATE();
blog
id title ctime
1 asdf 2019-11
2 asdf 2019-11
3 asdf 2019-10
4 asdf 2019-10
select ctime,count(1) from blog group ctime
select DATE_FORMAT(ctime, "%Y-%m"),count(1) from blog group DATE_FORMAT(ctime, "%Y-%m")
2019-11 2
2019-10 2
自定義函數(有返回值):
delimiter \\
create function f1(
i1 int,
i2 int)
returns int
BEGIN
declare num int default 0;
set num = i1 + i2;
return(num);
END \\
delimiter ;
SELECT f1(1,100);
4. 存儲過程
保存在MySQL上的一個別名 => 一坨SQL語句
別名()
用於替代程序員寫SQL語句
方式一:
MySQL: 存儲過程
程序:調用存儲過程
方式二:
MySQL:。。
程序:SQL語句
方式三:
MySQL:。。
程序:類和對象(SQL語句)
1. 簡單
create procedure p1()
BEGIN
select * from student;
INSERT into teacher(tname) values("ct");
END
call p1()
cursor.callproc(‘p1‘)
2. 傳參數(in,out,inout)
delimiter //
create procedure p2(
in n1 int,
in n2 int
)
BEGIN
select * from student where sid > n1;
END //
delimiter ;
call p2(12,2)
cursor.callproc(‘p2‘,(12,2))
3. 參數 out
delimiter //
create procedure p3(
in n1 int,
inout n2 int
)
BEGIN
set n2 = 123123;
select * from student where sid > n1;
END //
delimiter ;
set @v1 = 10;
call p2(12,@v1)
select @v1;
set @_p3_0 = 12
ser @_p3_1 = 2
call p3(@_p3_0,@_p3_1)
select @_p3_0,@_p3_1
cursor.callproc(‘p3‘,(12,2))
r1 = cursor.fetchall()
print(r1)
cursor.execute(‘select @_p3_0,@_p3_1‘)
r2 = cursor.fetchall()
print(r2)
=======> 特殊
a. 可傳參: in out inout
b. pymysql
cursor.callproc(‘p3‘,(12,2))
r1 = cursor.fetchall()
print(r1)
cursor.execute(‘select @_p3_0,@_p3_1‘)
r2 = cursor.fetchall()
print(r2)
為什麽有結果集又有out偽造的返回值?
delimiter //
create procedure p3(
in n1 int,
out n2 int 用於標識存儲過程的執行結果 1,2
)
BEGIN
insert into vv(..)
insert into vv(..)
insert into vv(..)
insert into vv(..)
insert into vv(..)
insert into vv(..)
END //
delimiter ;
4. 事務
delimiter //
create procedure p4(
out status int
)
BEGIN
1. 聲明如果出現異常則執行{
set status = 1;
rollback;
}
開始事務
-- 由秦兵賬戶減去100
-- 方少偉賬戶加90
-- 張根賬戶加10
commit;
結束
set status = 2;
END //
delimiter ;
===============================
delimiter \\
create PROCEDURE p5(
OUT p_return_code tinyint
)
BEGIN
DECLARE exit handler for sqlexception
BEGIN
-- ERROR
set p_return_code = 1;
rollback;
END;
START TRANSACTION;
DELETE from tb1;
insert into tb2(name)values(‘seven‘);
COMMIT;
-- SUCCESS
set p_return_code = 2;
END\\
delimiter ;
5. 遊標
delimiter //
create procedure p6()
begin
declare row_id int; -- 自定義變量1
declare row_num int; -- 自定義變量2
declare done INT DEFAULT FALSE;
declare temp int;
declare my_cursor CURSOR FOR select id,num from A;
declare CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
open my_cursor;
xxoo: LOOP
fetch my_cursor into row_id,row_num;
if done then
leave xxoo;
END IF;
set temp = row_id + row_num;
insert into B(number) values(temp);
end loop xxoo;
close my_cursor;
end //
delimter ;
6. 動態執行SQL(防SQL註入)
delimiter //
create procedure p7(
in tpl varchar(255),
in arg int
)
begin
1. 預檢測某個東西 SQL語句合法性
2. SQL =格式化 tpl + arg
3. 執行SQL語句
set @xo = arg;
PREPARE xxx FROM ‘select * from student where sid > ?‘;
EXECUTE xxx USING @xo;
DEALLOCATE prepare prod;
end //
delimter ;
call p7("select * from tb where id > ?",9)
===>
delimiter \\
CREATE PROCEDURE p8 (
in nid int
)
BEGIN
set @nid = nid;
PREPARE prod FROM ‘select * from student where sid > ?‘;
EXECUTE prod USING @nid;
DEALLOCATE prepare prod;
END\\
delimiter ;
Python-視圖 觸發器 事務 存儲過程