1. 程式人生 > 其它 >Mysql優化儲存過程儲存函式

Mysql優化儲存過程儲存函式

技術標籤: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;