Mysql優化儲存過程儲存函式
阿新 • • 發佈:2021-01-21
技術標籤:Mysql
儲存過程和函式是在資料庫中定義一些SQL語句的集合,然後直接呼叫這些儲存過程和函式來執行已經定義好的SQL語句。儲存過程和函式可以避免開發人員重複的編寫相同的SQL語句。而且,儲存過程和函式是在MySQL伺服器中儲存和執行的,可以減少客戶端和伺服器端的資料傳輸
儲存函式 | 儲存過程 |
---|---|
不能擁有輸出引數 | 可以擁有輸出引數 |
可以直接呼叫儲存函式,不需要call語句 | 需要call語句呼叫儲存過程 |
必須包含一條return語句 | 不允許包含return語句 |
一、建立儲存過程
因為;分會衝突,所以要加delimiter //。將//設定為結束執行符號
delimiter //#宣告儲存過程的結束符號為//
create procedure sp_name()
begin
.........sql語句
end //
delimiter ;#重新宣告分號為結束符號
二、呼叫儲存過程
call sp_name()
注意:儲存過程名稱後面必須加括號,哪怕該儲存過程沒有引數傳遞
三、刪除儲存過程
drop procedure sp_name//
注意:不能在一個儲存過程中刪除另一個儲存過程,只能呼叫另一個儲存過程
四、查詢儲存過程
四種方式
select `name` from mysql.proc where db = '資料庫' and `type` = 'PROCEDURE' //儲存過程
select * from mysql.proc where db = 'xx' and `type` = 'PROCEDURE' and name='xx'
select `name` from mysql.proc where db = 'xx' and `type` = 'FUNCTION' //函式
show procedure status; //儲存過程
show function status; //函式
4.1儲存過程具體語句
show create procedure sp_name\G;
五、儲存過程語法結構
5.1、區域性變數宣告
在儲存過程體中可以宣告區域性變數,用來儲存儲存過程體中臨時結果。
DECLARE var_name[,…] type [DEFAULT value]
Var_name:指定區域性變數的名稱 ,多個變數名用逗號分割
Type:用於宣告區域性變數的資料型別
default子句:用於為區域性變數指定一個預設值。若沒有指定,預設為null.
SET 變數賦值
declare age int default 1;
SET age = 10;
delimiter //
create procedure sp_name()
begin
declare age int default 1;
declare num int default 0;
SET num = 10;
select concat('age的值:',age)
end //
delimiter ;
呼叫
call sp_name();
into賦值
DROP PROCEDURE IF EXISTS contStById;
DELIMITER // -- 定義儲存過程結束符號為//
CREATE PROCEDURE contStById()
BEGIN
DECLARE sCount INT;
//把t_student 表的總數,查出來賦值給 sCount
SELECT COUNT(*) INTO sCount FROM t_student;
SELECT CONCAT('sCount 的值是:',sCount);
END // -- 結束符要加
DELIMITER ; -- 重新定義儲存過程結束符為分號
CALL contStById();
5.2、條件語句
if 條件 then
statement
else
statement
end if;
DROP PROCEDURE IF EXISTS testIf;
DELIMITER //
CREATE PROCEDURE testIf()
BEGIN
DECLARE val VARCHAR(255);
DECLARE result VARCHAR(255);
SET val = 'a';
IF val IS NULL
//條件ture執行then
THEN SET result = 'IS NULL';
//如果var=b 執行
ELSEIF var=='b'
THEN SET result ='wo';
//都不滿足執行else
ELSE SET result = 'IS NOT NULL';
END IF;
SELECT CONCAT('最終資訊;',result );
END //
DELIMITER ;
CALL testIf();
5.3、傳遞引數
語法: CREATE PROCEDURE sp_name(定義IN/OUT/INOUT) 引數名 引數型別)
BEGIN
SQL語句;
END
IN 表示輸入引數,預設是IN
OUT表示輸出引數,
INOUT表示既可以輸入也可以輸出的引數。
sp_name為儲存過程的名字。
如果此儲存過程沒有任何輸入輸出,其實就沒什麼意義了,但是sp_name()的括號不能省略
out
DROP PROCEDURE IF EXISTS testIf;
DELIMITER //
CREATE PROCEDURE testIf(OUT result VARCHAR(255))
BEGIN
DECLARE val VARCHAR(255);
SET val = 'a';
IF val IS NULL
THEN SET result = 'IS NULL';
ELSE SET result = 'IS NOT NULL';
END IF;
END //
DELIMITER ;
//@result用來接收輸出的result,mysql中 @代表使用者的會話變數
CALL testIf(@result);
SELECT @result;
綜合
DROP PROCEDURE IF EXISTS getStuById;
DELIMITER // -- 定義儲存過程結束符號為//
CREATE PROCEDURE getStuById(IN stuId INT(11),OUT stuName VARCHAR(255),OUT stuAge INT(11)) -- 定義輸入與輸出引數
COMMENT 'query students by their id' -- 提示資訊
//SQL SECURITY DEFINER -- DEFINER指明只有定義此SQL的人才能執行,MySQL預設也是這個
BEGIN
//age INTO stuName 把表查出來的變數賦值給輸出變數stuName
SELECT name ,age INTO stuName , stuAge FROM t_student WHERE id = stuId; -- 分號要加
END // -- 結束符要加
DELIMITER ; -- 重新定義儲存過程結束符為分號
#study 是當前資料庫名稱
CALL study.getStuById(1,@name,@age);
SELECT @name AS stuName,@age AS stuAge;
5.4 條件(2)CASE語句
DROP PROCEDURE IF EXISTS testCase;
DELIMITER //
CREATE PROCEDURE testCase(OUT result VARCHAR(255))
BEGIN
DECLARE val VARCHAR(255);
CASE
WHEN 表示式 THEN SET result = 'val is true';
WHEN 表示式 THEN SET result = 'val is false';
ELSE SELECT 'else';
END CASE;
// SELECT CONCAT('result ',result ) as result
END //
DELIMITER ;
CALL testCase(@result);
SELECT @result;