1. 程式人生 > >Python-視圖 觸發器 事務 存儲過程

Python-視圖 觸發器 事務 存儲過程

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-視圖 觸發器 事務 存儲過程