MySQL學習筆記(五)存儲過程

存儲引擎

輸入SQL命令,MySQL引擎對命令進行分析,查看輸入的語法是否正確,如果正確,再進行編譯,編譯成MySQL引擎可識別的命令,最后再進行執(zhí)行,并將執(zhí)行結(jié)果返回給客戶端。

如果省略了語法分析和編譯的階段,則效率可提高。

存儲過程:

是SQL語句和控制語句的預編譯集合,以一個名稱存儲并作為一個單元處理(類似函數(shù))。存儲過程存儲在數(shù)據(jù)庫內(nèi),可以由應用程序調(diào)用執(zhí)行,而且允許用戶申明變量以及進行流程控制。存儲過程可以接受輸入類型的參數(shù)和輸出類型的參數(shù),并且可以存在多個返回值。只在第一次調(diào)用時進行語法分析和編譯,以后的調(diào)用直接調(diào)用編譯的結(jié)果,效率大大提高。

優(yōu)點:
1、增強SQL語句的功能和靈活性:可以通過控制語句對流程進行控制和判斷
2、實現(xiàn)較快的執(zhí)行速度:客戶端第一次調(diào)用存儲過程時,MySQL引擎會對其進行語法分析、編譯等操作,然后將編譯結(jié)果存儲到內(nèi)存中,所以第一次和之前的效率一樣,然而以后會直接調(diào)用內(nèi)存中的編譯結(jié)果,效率提高
3、減少網(wǎng)絡流量:例如刪除一個記錄,我們原本要輸入DELETE FROM xx WHERE ...; 要傳輸?shù)淖址^多,如果寫成存儲過程,就只要調(diào)用存儲過程的名字和相應參數(shù)就行,傳輸?shù)淖址麛?shù)量較少,所以減少了網(wǎng)絡流量。

1、存儲過程語法結(jié)構(gòu)分析

 CREATE
 [DEFINER = {userCURRENT_USER}]//定義時的用戶,若是不寫就默認為當前用戶
 PROCEDURE sp_name ([proc_parameter[,...]]) //可以帶0到多個參數(shù)
 [characteristic ...] routine_body
 其中參數(shù)
 proc_parameter:
 [IN OUT INOUT] param_name type
 IN, 表示該參數(shù)的值必須在調(diào)用存儲過程時指定
 OUT, 表示該參數(shù)的值可以被存儲過程改變,并且可以返回
 INOUT, 表示該參數(shù)的值調(diào)用時指定,并且可以被改變和返回

 2.特性

 COMMENT 'string'
 {CONTAINS SQLNO SQLREADS SQL DATAMODIFIES SQL DATASQL SECURITY{DEFINERINVOKER}
 COMMENT:注釋
 CONTAINS SQL:包含SQL語句, 但不包含讀或?qū)憯?shù)據(jù)的語句
 NO SQL:不包含SQL語句
 READS SQL DATA:包含讀數(shù)據(jù)的語句
 MODIFIES SQL DATA:包含寫數(shù)據(jù)的語句
 SQL SECURITY {DEFINERINVOKER}指明誰有權(quán)限來執(zhí)行

 3.過程體

 (1)過程體由合法的SQL語句構(gòu)成;
 (2)過程體可以是任意SQL語句;對表格進行增刪,連接,但是不能創(chuàng)建數(shù)據(jù)表<br>
 (3)過程體如果為復合結(jié)構(gòu)則使用BEGIN...END語句
 (4)復合結(jié)構(gòu)可以使用條件、循環(huán)等控制語句

創(chuàng)建不帶參數(shù)的存儲過程:
 1.創(chuàng)建沒有參數(shù)的存儲過程
 CREATE PROCEDURE sp1() SELECT VERSION();
 2.調(diào)用存儲過程
 CALL sp_name([parameter[,...]]) - 帶參數(shù)的存儲過程的調(diào)用
 CALL sp_name[()] - 不帶參數(shù)的存儲過程調(diào)用
 CALL sp1;
 CALL sp1();

1.創(chuàng)建帶有INT類型參數(shù)的存儲過程
DESC users;
DELIMITER //
CREATE PROCEDURE removeUserByID(IN id INT UNSIGNED)
BEGIN
DELETE FROM users WHERE id = id;
END
//
DELIMITER ;
CALL removeUserById(3); //參數(shù)名稱最好不要和表中的字段相同
SELECT * FROM users; //全刪除了
DELIMITER //
CREATE PROCEDURE removeUserById(IN p_id INT UNSIGNED)
BEGIN DELETE FROM users WHERE id = p_id;
END
//
DELIMITER ;
SELECT * FROM users;
CALL removeUserById(22);
SELECT * FROM users WHERE id = 22;

2.修改存儲過程
ALTER PROCEDURE sp_name [characteristic]
COMMENT 'string'
|{CONTAINS SQL|NO SQL|READS SQL DATA|MODIFIES SQL DATA}
|SQL SECURITY{DEFINER|INVOKER}
3.刪除存儲過程
DROP PROCEDURE [IF EXISTS] sp_name;
DROP removeUserById;

1.用戶變量:以"@"開始,形式為"@變量名"

用戶變量跟mysql客戶端是綁定的,設置的變量,只對當前用戶使用的客戶端生效

2.全局變量:定義時,以如下兩種形式出現(xiàn),set GLOBAL 變量名  或者  set @@global.變量名 

對所有客戶端生效。只有具有super權(quán)限才可以設置全局變量

3.會話變量:只對連接的客戶端有效。

4.局部變量:作用范圍在begin到end語句塊之間。在該語句塊里設置的變量

declare語句專門用于定義局部變量。set語句是設置不同類型的變量,包括會話變量和全局變量

創(chuàng)建帶有多個OUT類型參數(shù)的存儲過程:

1.明確什么是OUT類型的參數(shù),有什么作用?

答:OUT類型參數(shù),表示在調(diào)用存儲過程時,該參數(shù)的值可以被存儲過程改變,并且返回一個值。通常是這種類型時,調(diào)用時寫入的參數(shù)都是變量用“@”符號開頭的變量,在BEGIN和END之中的變量是局部變量,在調(diào)用存儲過程時寫入的變量是“用戶變量”,比如有一個存儲過程的名稱叫做“addUser()”,調(diào)用時addUser(@sum),sum就是用戶變量。

2.ROW_COUNT()函數(shù)就相當于PHP的MySQL函數(shù)庫中的mysql_affected_rows()這個函數(shù),兩者的作用都是相同的,都是計算當插入記錄和修改記錄、以及添加和刪除記錄時的個數(shù)總和的。

3.例子:

SELECT ROW_COUNT() INTO delete_User ;是指調(diào)用ROW_COUNT()這個函數(shù),并且把返回值存儲在delete_User這個局部變量中。
SELECT COUNT(id) FROM users INTO remain_User ;是指在刪除用戶后,調(diào)用COUNT()函數(shù)對剩下的用戶數(shù)做一個統(tǒng)計,在哪張表中要說明清楚,然后把返回值存儲在remain_User這個局部變量中。
【因為delete_User和remain_User是OUT類型的參數(shù),所以會返回一個值給調(diào)用時的用戶變量,用"SELECT @a,@b"可以知道返回的值是多少了】

//創(chuàng)建帶有多個OUT類型參數(shù)的存儲過程
DESC users; 
SELECT * FROM users;
SELECT ROW_COUNT(); //
DESC test;
INSERT test(username) VALUES('A'),('B,'),('C');
SELECT ROW_COUNT(); //返回被插入的記錄總數(shù)
SELECT * FROM test;
UPDATE test SET username = CONTCAT(username, '--immoc') WHERE id <= 2;
SELECT row_COUNT(); //得到被更新的記錄總數(shù)
DELIMITER //
CREATE PROCEDURE rmUserByAgeAndRtInfos(IN p_age SMALLINT UNSIGNED, OUT delNums SMALLINT UNSIGNED, OUT leftNums SMALLINT UNSIGNED)
BEGIN
DELETE FROM users WHERE WHERE age = p_age; //注意變量不同
SELECT ROW_COUNT() INTO delNums;
SELECT COUNT(id) FROM users INTO leftNums;
END
//
DELIMITER ;
SELECT * FROM users;
SELECT COUNT(id) FROM users WHERE age = 20;
CALL rmUserByAgeAndRtInfos(20, @a, @b);
SELECT * FROM users;
SELECT COUNT(id) FROM users WHERE age = 23;
CALL rmUserByAgeAndRtInfos(23, @a, @b);
SELECT @a, @b;
存儲過程與自定義函數(shù)的區(qū)別
//存儲過程與自定義函數(shù)的區(qū)別
A、存儲過程實現(xiàn)的功能相對復雜,函數(shù)針對性較強
B、存儲過程可以返回多個值,函數(shù)只能有一個返回值
C、存儲過程一般獨立執(zhí)行,函數(shù)可以作為 sql 語句的組成部分來出現(xiàn)


//修改存儲過程
alter procedure sp_name [characteristic ...] 
comment 'string'
| {contains sql | no sql | reads sql data | modifies sql data} | sql security {definer | invoker}
存儲過程只能修改簡單的特性,并不能修改過程體

//刪除存儲過程
DROP PROCEDURE [IF EXISTS] sp_name;

1、存儲過程:是SQL語句和控制語句的預編譯集合,以一個名字存儲并作為一個單元來處理。
2、參數(shù):輸入類型 輸出類型 輸入&&是輸出
3、創(chuàng)建:CREATE...PROCEDURE...
4、注意事項:
(1)創(chuàng)建存儲過程或自定義函數(shù)時需要通過delimiter語句修改定界符。
(2)如果函數(shù)體或過程題有多個語句,需要包含在BEGIN...END語句塊中。
(3)存儲過后才能通過call來調(diào)用。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

  • 當一個大型系統(tǒng)在建立時,會發(fā)現(xiàn),很多的SQL操作是有重疊的,個別計算是相同的,比如:業(yè)務系統(tǒng)中,計算一張工單的計算...
    JackFrost_fuzhu閱讀 3,517評論 0 27
  • 1. Java基礎部分 基礎部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,697評論 18 399
  • 原文鏈接 MySQL存儲過程詳解 1.存儲過程簡介 我們常用的操作數(shù)據(jù)庫語言SQL語句在執(zhí)行的時候需要要先編譯,然...
    亞斯咪妮閱讀 2,723評論 1 30
  • 轉(zhuǎn)載自這里 存儲過程簡介 我們常用的操作數(shù)據(jù)庫語言SQL語句在執(zhí)行的時候需要要先編譯,然后執(zhí)行,而存儲過程(Sto...
    杜七閱讀 2,470評論 4 27
  • 小時候最喜歡看的就是武俠片了,刀光劍影、快意恩仇、仗劍而行、瀟灑從容,既滿足了視覺享受,重要的是喜歡那種把自己代入...
    以風閱讀 377評論 0 0

友情鏈接更多精彩內(nèi)容