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 ;
游標
游標的性能雖然不高但是能實作回圈的效果,對于每一行資料要進行分開計算的時候我們才需要用到游標
先創建兩個表t2、t3,然后實作t3中每行score的值等于每行t2中id+score的值
t2:

t3:

存盤程序代碼:
delimiter // create procedure p5() begin declare p_id int; declare p_score int; declare done int default false; declare temp int; declare my_cursor cursor for select id,score from t2; declare continue handler for not found set done = true; open my_cursor; p_l:loop fetch my_cursor into p_id,p_score; if done then leave p_l; end if; set temp = p_id + p_score; insert into t3(score) values(temp); end loop p_l; close my_cursor; end // delimiter ;
執行p5:
call p5();
結果:

動態執行SQL(防SQL注入)
delimiter // create procedure p7( in arg int ) -- 預檢測SQL陳述句是否具有合法性 begin set @ppp = arg; prepare prod from 'select * from studenttable where sid > ?'; execute prod using @ppp; deallocate prepare prod; end // delimiter ;
call p7(15)
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/117972.html
標籤:MySQL
上一篇:MySQL復制從庫建立-xtracebackup方式
下一篇:mysql_常用操作命令
