MySQL從刪庫到跑路_高級(四)——存儲過程

做者:天山老妖S程序員

連接:http://blog.51cto.com/9291927sql

 

1、存儲過程簡介

一、存儲過程簡介數據庫

存儲過程是一組具備特定功能的SQl語句集組成的可編程的函數,經編譯建立並保存在數據庫中,用戶可經過指定存儲過程的名字並給定參數來調用執行。編程

存儲過程是數據庫管理中經常使用的技術之一,能夠很方便的作些相似數據統計、數據分析等工做,SQL SERVER、ORACLE、MySQL都支持存儲過程,但不一樣的數據庫環境語法結構有所區別。安全

二、存儲過程的優勢微信

A、存儲過程加強了SQL語言的功能和靈活性。存儲過程能夠用流控制語句編寫,有很強的靈活性,能夠完成複雜的判斷和較複雜的運算。網絡

B、存儲過程容許標準組件式編程。存儲過程被建立後,能夠在程序中被屢次調用,而沒必要從新編寫該存儲過程的SQL語句。並且數據庫專業人員能夠隨時對存儲過程進行修改,對應用程序源代碼毫無影響。函數

C、存儲過程能實現較快的執行速度。若是某一操做包含大量的Transaction-SQL代碼或分別被屢次執行,那麼存儲過程要比批處理的執行速度快不少。由於存儲過程是預編譯的。在首次運行一個存儲過程時查詢,優化器對其進行分析優化,而且給出最終被存儲過程在系統表中的執行計劃。而批處理的Transaction-SQL語句在每次運行時都要進行編譯和優化,速度相對要慢一些。優化

D、存儲過程可以減小網絡流量。針對同一個數據庫對象的操做(如查詢、修改),若是操做所涉及的Transaction-SQL語句被組織存儲過程,那麼當在客戶計算機上調用該存儲過程時,網絡中傳送的只是該調用語句,從而大大增長了網絡流量並下降了網絡負載。網站

E、存儲過程可被做爲一種安全機制來充分利用。系統管理員經過執行某一存儲過程的權限進行限制,可以實現對相應的數據的訪問權限的限制,避免了非受權用戶對數據的訪問,保證了數據的安全。

2、存儲過程的使用

一、存儲過程的建立

建立存儲過程的語法:

CREATE    [DEFINER = { user | CURRENT_USER }]  PROCEDURE sp_name ([proc_parameter[,...]])    [characteristic ...] routine_body proc_parameter:    [ IN | OUT | INOUT ] param_name typecharacteristic:    COMMENT 'string'  | LANGUAGE SQL  | [NOT] DETERMINISTIC  | { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }  | SQL SECURITY { DEFINER | INVOKER } routine_body:   Valid SQL routine statement[begin_label:] BEGIN  [statement_list]     END [end_label]

IN輸入參數:表示該參數的值必須在調用存儲過程時指定,在存儲過程當中修改改參數的值不能被返回,爲默認值。

OUT輸出參數:該值可在存儲過程內部被改變,並可返回。

INOUT輸入輸出參數:調用時指定,而且可被改變和返回。

A、無參數的存儲過程建立

建立查找平均分最高的前三名同窗的存儲過程

create procedure getMax() BEGIN select a.sname as '姓名', AVG(b.mark) as '平均分' from TStudent a join TScore b on a.studentID = b.studentID group by b.studentID order by '平均分' DESC limit 3; END;

B、帶輸入參數的存儲過程建立

查找指定班級的平均分最高的前三名學生

create procedure getMaxByClass(in classname VARCHAR(10)) BEGIN select a.sname as '姓名', AVG(b.mark) as '平均分' from TStudent a join TScore b on a.studentID = b.studentID where a.class = classname group by b.studentID order by '平均分' DESC limit 3; END

C、帶輸入參數和輸出參數的存儲過程建立

根據輸入的班級,找到學號最大的學生,將學號存儲到輸出參數。

create procedure getMaxSIDByClass(IN classname VARCHAR(20), out maxid int) BEGIN select MAX(studentID) into maxid from TStudent where class = classname; END;

二、存儲過程的刪除

drop procedure sp_name;

不能在一個存儲過程當中刪除另外一個存儲過程,只能調用另外一個存儲過程。

三、存儲過程的調用

call sp_name[(傳參)];

存儲過程名稱後面必須加括號,即便存儲過程沒有參數傳遞。

四、存儲過程信息的查看

show procedure status;

顯示數據庫中全部存儲的存儲過程基本信息,包括所屬數據庫,存儲過程名稱,建立時間等。

show create procedure sp_name;

顯示某一個存儲過程的詳情信息。

五、使用存儲過程插入數據

create procedure insertTStudent(in sid CHAR(5), name CHAR(10), ssex CHAR(1) ) BEGIN insert into TStudent (studentID, sname, sex) VALUES(sid, name, ssex); select * from TStudent where studentID = sid; END; call insertTStudnet('01020','孫悟空','男');

六、使用存儲過程刪除數據

根據提供的學號刪除學生的學生成績,再刪除學生

create procedure deleteStudent(in sid CHAR(5) ) BEGIN delete from TScore where studentID = sid; delete from TStudent wheres studentID = sid; END;

七、使用存儲過程備份還原數據

A、使用存儲過程備份數據

建立存儲過程備份學生表,根據指定的代表建立新表,將TStudent表中的記錄導入到新表。

create procedure backupStudent(in tablename CHAR(10))BEGINset @sql1=CONCAT('create table ',tablename,' ( studentID VARCHAR(5), sname VARCHAR(10), sex CHAR(1), cardID VARCHAR(20), Birthday DATETIME, email VARCHAR(20), class VARCHAR(10), enterTime DATETIME )');prepare CT1 from @sql1;EXECUTE CT1;set @sql2=CONCAT('insert into ', tablename, '(studentID,sname,sex,cardID,Birthday,email,class,enterTime) select studentID,sname,sex,cardID,Birthday,email,class,enterTime from TStudent');PREPARE CT2 from @sql2;EXECUTE CT2;END;call backupStudent('table2019');

B、使用當前時間做爲表名備份數據

建立存儲過程,使用系統當前事件構造新的表名,備份Tstudent表中的記錄。

create procedure backupStudentByDateTime()BEGINDECLARE tablename VARCHAR(20);set tablename = CONCAT('Table', REPLACE(REPLACE(REPLACE(now(),' ',''),':',''),'-',''));set @sql1=CONCAT('create table ',tablename,' ( studentID VARCHAR(5), sname VARCHAR(10), sex CHAR(1), cardID VARCHAR(20), Birthday DATETIME, email VARCHAR(20), class VARCHAR(10), enterTime DATETIME )');prepare CT1 from @sql1;EXECUTE CT1;set @sql2=CONCAT('insert into ', tablename, '(studentID,sname,sex,cardID,Birthday,email,class,enterTime) select studentID,sname,sex,cardID,Birthday,email,class,enterTime from TStudent');PREPARE CT2 from @sql2;EXECUTE CT2;ENDcall backupStudentByDateTime();

C、使用存儲過程還原數據

建立存儲過程,根據輸入的學號從指定的表還原學生記錄,存儲過程先刪除指定的學號的TStudent表中學生記錄,再從指定的表中插入該學生到Tstudent表。

create procedure restoreStudent(in sid VARCHAR(5), in tablename VARCHAR(20))BEGINset @sql1=concat('delete from TStudent where studentid=',sid);prepare CT1 from @sql1;EXECUTE CT1;set @sql2=concat('insert into TStudent (Studentid,sname,sex,cardID,Birthday,Email,Class,enterTime)  select Studentid,sname,sex,cardID,Birthday,Email,Class,enterTime  from ',tablename,' where studentid=',sid);prepare CT2 from @sql2;EXECUTE CT2;END;

修改某個學生的記錄

update TStudent set sname = '孫悟空' where studentID = '00997';

從指定表中恢復數據

call restore Student('00997','Table20180404215950');

查看恢復的結果

select * from TStudent where studentID = '00997';

3、存儲過程實例

一、增長學生到數據庫表

create procedure addStudent(in num int) begin declare i int; set i=1;delete from TStudent;while num>=i doinsert TStudent values (       LPAD(convert(i,char(5)),5,'0'),       CreateName(),       if(ceil(rand()*10)%2=0,'男','女'),       RPAD(convert(ceil(rand()*1000000000000000000),char(18)),18,'0'),       Concat(convert(ceil(rand()*10)+1980,char(4)),'-',LPAD(convert(ceil(rand()*12),char(2)),2,'0'),'-',LPAD(convert(ceil(rand()*28),char(2)),2,'0')),       Concat(PINYIN(sname),'@hotmail.com'),       case ceil(rand()*3) when 1 then '網絡與網站開發' when 2 then 'JAVA' ELSE 'NET' END,       NOW() ); set i=i+1; end while;select * from TStudent; end

二、給學生添加成績

create procedure fillScore() begin DECLARE St_Num INT; DECLARE Sb_Num INT; DECLARE i1 INT; DECLARE i2 INT;set i1=1;set i2=1; delete from TScore;select count(*) into St_Num from TStudent;select count(*) into Sb_Num from TSubject;while St_Num>=i1 doset i2=1;while Sb_Num>=i2 doinsert TScore values (LPAD(convert(i1,char(5)),5,'0'),LPAD(convert(i2,char(4)),4,'0'),ceil(50+rand()*50));set i2=i2+1; END WHILE;set i1=i1+1; END WHILE; end

 

喜歡的小夥伴們能夠搜索咱們我的的微信公衆號「程序員的成長之路」點擊關注或掃描下方二維碼

相關文章
相關標籤/搜索