存儲引擎
輸入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)用。