Mysql存儲過程 存儲過程是保存在Mysql上的一個別名(就是一堆SQL語句),使用別名就可以查到結果不用再去寫SQL語句。存儲過程用於替代程式員寫SQL語句。 創建存儲過程 當我們寫完這段代碼並執行,再去調用p1()就可以直接執行裡面的查詢 執行結果: 這樣的好處能讓功能代碼都整合到一塊且不用再 ...
Mysql存儲過程
存儲過程是保存在Mysql上的一個別名(就是一堆SQL語句),使用別名就可以查到結果不用再去寫SQL語句。存儲過程用於替代程式員寫SQL語句。
創建存儲過程
delimiter // CREATE PROCEDURE p1() BEGIN SELECT * FROM studenttable; INSERT INTO teachertable(tname) VALUES('陳晨'); END // delimiter ;
當我們寫完這段代碼並執行,再去調用p1()就可以直接執行裡面的查詢
call p1();
執行結果:
這樣的好處能讓功能代碼都整合到一塊且不用再去寫SQL語句,不好之處在於如果要改資料庫中的資料,那不一定能從存儲過程中能拿到數據。
在公司處理數據時選用的方式:
方式一:
Mysql(DBA):存儲過程
程式(程式員):調用存儲過程
方式二:
Mysql:什麼都不做
程式:寫SQL語句
方式三:
Mysql:什麼都不做
程式:類和對象(本質就是SQL語句 )
通過Python中的pymysql模塊拿到p1的數據:
import pymysql conn = pymysql.connect(host = 'localhost',user = 'root',password = '',database = 'db2',charset = 'utf8') cursor = conn.cursor() cursor.callproc('p1') conn.commit() result = cursor.fetchall() print(result) cursor.close() conn.close()
傳參數in
in表示傳入一個值
delimiter // CREATE PROCEDURE p2( IN pid INT, IN pnumber INT ) BEGIN SELECT * FROM scoretable WHERE student_id > pid AND number > pnumber; END // delimiter ;
呼叫執行過程p2並帶入參數
call p2(15,90);
這樣就能找到大於學生ID15並且分數大於90 的學生成績
利用pymysql執行達到相同效果:
cursor.callproc('p2',(15,80))
傳參數out
out偽造了一個返回值,主要用於表示存儲過程的執行結果
delimiter // create procedure p3( in pid int, out pnumber int ) begin set pnumber = 80; select student_id from scoretable where student_id > pid and number > pnumber group by student_id; end // delimiter ;
呼叫執行過程p3並帶入參數
set @pn = 80; call p3(20,@pn); select @pn;
在pymysql中執行
import pymysql conn = pymysql.connect(host = 'localhost',user = 'root',password = '',database = 'db2',charset = 'utf8') cursor = conn.cursor() cursor.callproc('p3',(15,80)) r1 = cursor.fetchall() print(r1) cursor.execute('select @_p3_0,@_p3_1') #返回前面寫的這兩個參數15 80 r2 = cursor.fetchall() print(r2) cursor.close() conn.close()
傳參數inout
結合in和out兩種特性
事務
比方說雙方進行一筆交易,但出現某種錯誤,一方支付了錢另一方沒有收到,就可以通過事務回滾到最初的狀態
delimiter // create procedure p4( out p_status tinyint -- 狀態變數,用於判斷是否出現執行異常 ) begin declare exit handler for sqlexception -- 執行出現異常的代碼 begin set p_status = 1; -- 1表示出現異常 rollback; -- 將事務回滾 end ; start transaction; -- 開始事務 select student_id from scoretable group by student_id; insert into scoretable(student_id,course_id,number) values(25,3,78); commit; -- 結束事務 set p_status = 2; -- 2表示沒有出現異常 end // delimiter ;
......