mysql8學習筆記18--存儲過程和函數


• create procedure用來創建存儲過程,create function用來創建函數

• 函數與存儲過程最大的區別就是函數調用有返回值,調用存儲過程用call語句,而調用函數就直接引用函數名+參數即可

• Definer和sql security子句指定安全環境
• Definder是MySQL的特殊的訪問控制手段,當數據庫當前沒有這個用戶權限時,執行存儲過程可能會報錯
• sql secuirty的值決定了調用存儲過程的方式,取值 :definer(默認)或者invoker definer:在執行存儲過程前驗證definer對應的用戶如:cdq@127.0.0.1是否存在,以及是否具有執行存儲過程的權限,若沒有則報錯invoker:在執行存儲過程時判斷inovker即調用該存儲過程的用戶是否有相應權限,若沒有則報錯
• IN,OUT,INOUT三個參數前的關鍵詞只適用於存儲過程,對函數而言所有的參數默認都是輸入參數
• IN輸入參數用於把數值傳入到存儲過程中;OUT輸出參數將數值傳遞到調用者,初始值是NULL;INOUT輸入輸出參數把數據傳入到存儲過程,在存儲過程中修改之后再傳遞到調用者
• Delimiter命令是改變語句的結束符,MySQL默認的結束符為;號,由於procedure和function中的;號並不代表創建的結束,所以要替換成另外的結束符以便表示創建的結束
• Rontine_body子句可以包含一個簡單的SQL語句,也可以包含多個SQL語句,通過begin…end將這多個SQL語句包含在一起
• MySQL存儲過程和函數中也可以包含類似create和drop等DDL語句
• Comment子句用來寫入對存儲過程和函數的注釋
• Language子句用來表示此存儲過程和函數的創建語言
• 存儲過程和函數被標注為deterministic表明當輸入相同的參數是會返回相同的結果,反之如果是not deterministic則表示相同參數不會是相同結果,默認是not deterministic
• 相關屬性短語只有咨詢含義,並不是強制性的約束
• Contains sql表明此存儲過程或函數不包含讀或者寫數據的語句,這是默認屬性
• NO SQL表示此存儲過程或函數不包含SQL語句
• Reads sql data表示此存儲過程包含諸如select的查詢數據的語句,但不包含插入或刪除數據的語句
• Modifies sql data表示此存儲過程包含插入或刪除數據的語句
 
• Drop procedure/function語句用來刪除指定名稱的存儲過程或函數
 
• If exists關鍵詞用來避免在刪除一個本身不存在的存儲過程或函數時,MySQL返回錯誤
 • Begin…end語句通常出現在存儲過程、函數和觸發器中,其中可以包含一個或多個語句,每個語句用;號隔開
 

創建存儲過程: 

/*在創建之前如果存在同名存儲過程,則刪除*/
drop PROCEDURE if EXISTS create_student;
/*修改分分隔符為;;*/
delimiter ;;

create PROCEDURE create_student (OUT new_stuid INT,IN new_name VARCHAR(10),IN birth date,IN addr VARCHAR(50),IN gender VARCHAR(10),IN sub_jct VARCHAR(10))
BEGIN
    /*為new_stuid聲明變量*/
    DECLARE new_stuid int;
    DECLARE stu_sex int;
    select max(stuid) into new_stuid from tb_student2;
    set new_stuid = new_stuid +1;

    case stu_sex
    WHEN gender='男生' THEN SET stu_sex=0;
    WHEN gender='女生' THEN SET stu_sex=1;
    else set stu_sex=2;
    END case;

    /*插入數據到tb_student2*/
    insert INTO tb_student2(stuid,stuname,stusex,stubirth,stuaddr,collid) VALUES(new_stuid,new_name,stu_sex,birth,addr,2);
    


END;;

delimiter ;

調用存儲過程:

mysql> call create_student(@new_stuid,"王超人",'1999-03-04','廣東深圳','男生','計算機');
Query OK, 1 row affected (0.08 sec)

mysql> select @new_stuid;
+------------+
| @new_stuid |
+------------+
|       NULL |
+------------+
1 row in set (0.00 sec)

mysql> select * from tb_student2;
+-------+--------------+--------+------------+--------------+--------+
| stuid | stuname      | stusex | stubirth   | stuaddr      | collid |
+-------+--------------+--------+------------+--------------+--------+
|  1001 | 張三         |      0 | 1990-03-04 | ABCabc       |      1 |
|  1002 | 季墨         |      0 | 1992-02-02 | 湖南長沙     |      1 |
|  1033 | 王語嫣       |      1 | 1989-12-03 | 四川成都     |      1 |
|  1378 | 紀嫣然       |      1 | 1995-08-12 | 四川綿陽     |      1 |
|  1572 | 張子文       |      0 | 1993-07-19 | 陝西咸陽     |      1 |
|  1954 | 張學友       |      0 | 1994-09-20 | 福建莆田     |      1 |
|  2035 | 東方不敗     |   NULL | 1988-06-30 | NULL         |      2 |
|  3011 | 金大牙       |      0 | 1985-12-12 | 福建莆田     |      3 |
|  3755 | 豬腳         |      0 | 1993-01-25 | NULL         |      3 |
|  3923 | 楊不悔       |      1 | 1985-04-17 | 四川成都     |      3 |
|  3924 | 王超人       |      2 | 1999-03-04 | 廣東深圳     |      2 |
|  3925 | 王超人2      |      2 | 1999-03-04 | 廣東深圳     |      2 |
+-------+--------------+--------+------------+--------------+--------+
12 rows in set (0.00 sec)

mysql> 

 把上面的例子改造成函數

/*在創建之前如果存在同名函數,則刪除*/
drop FUNCTION if EXISTS create_student_function;
/*修改分分隔符為;;*/
delimiter ;;

create FUNCTION create_student_function (new_name VARCHAR(10),birth date,addr VARCHAR(50),gender VARCHAR(10),sub_jct VARCHAR(10)) RETURNS INT
BEGIN
    /*為new_stuid聲明變量*/
    DECLARE new_stuid int;
    DECLARE stu_sex int;
    select max(stuid) into new_stuid from tb_student2;
    set new_stuid = new_stuid +1;

    case stu_sex
    WHEN gender='男生' THEN SET stu_sex=0;
    WHEN gender='女生' THEN SET stu_sex=1;
    else set stu_sex=2;
    END case;

    /*插入數據到tb_student2*/
    insert INTO tb_student2(stuid,stuname,stusex,stubirth,stuaddr,collid) VALUES(new_stuid,new_name,stu_sex,birth,addr,2);
    
    RETURN new_stuid;



END;;

delimiter ;

 調用函數

mysql> select create_student("王超人",'1999-03-04','廣東深圳','男生','計算機');          
ERROR 1305 (42000): FUNCTION school.create_student does not exist
mysql> select create_student_function("王超人",'1999-03-04','廣東深圳','男生','計算機');
+---------------------------------------------------------------------------------------+
| create_student_function("王超人",'1999-03-04','廣東深圳','男生','計算機')             |
+---------------------------------------------------------------------------------------+
|                                                                                  3926 |
+---------------------------------------------------------------------------------------+
1 row in set, 8 warnings (0.09 sec)

mysql> select create_student_function("王超人",'1999-03-04','廣東深圳','男生','計算機');
+---------------------------------------------------------------------------------------+
| create_student_function("王超人",'1999-03-04','廣東深圳','男生','計算機')             |
+---------------------------------------------------------------------------------------+
|                                                                                  3927 |
+---------------------------------------------------------------------------------------+
1 row in set (0.06 sec)

mysql> select create_student_function("王超人",'1999-03-04','廣東深圳','男生','計算機');
+---------------------------------------------------------------------------------------+
| create_student_function("王超人",'1999-03-04','廣東深圳','男生','計算機')             |
+---------------------------------------------------------------------------------------+
|                                                                                  3928 |
+---------------------------------------------------------------------------------------+
1 row in set (0.05 sec)

mysql> 

 

 

查看所有存儲例程:

mysql> show procedure status like '%create_student%';
+--------+----------------+-----------+---------+---------------------+---------------------+---------------+---------+----------------------+----------------------+--------------------+
| Db     | Name           | Type      | Definer | Modified            | Created             | Security_type | Comment | character_set_client | collation_connection | Database Collation |
+--------+----------------+-----------+---------+---------------------+---------------------+---------------+---------+----------------------+----------------------+--------------------+
| school | create_student | PROCEDURE | root@%  | 2020-08-08 23:08:22 | 2020-08-08 23:08:22 | DEFINER       |         | utf8                 | utf8_general_ci      | utf8_bin           |
+--------+----------------+-----------+---------+---------------------+---------------------+---------------+---------+----------------------+----------------------+--------------------+
1 row in set (0.00 sec)

mysql> show function status like '%create%';
+--------+-------------------------+----------+---------+---------------------+---------------------+---------------+---------+----------------------+----------------------+--------------------+
| Db     | Name                    | Type     | Definer | Modified            | Created             | Security_type | Comment | character_set_client | collation_connection | Database Collation |
+--------+-------------------------+----------+---------+---------------------+---------------------+---------------+---------+----------------------+----------------------+--------------------+
| school | create_student_function | FUNCTION | root@%  | 2020-08-09 16:47:51 | 2020-08-09 16:47:51 | DEFINER       |         | utf8                 | utf8_general_ci      | utf8_bin           |
+--------+-------------------------+----------+---------+---------------------+---------------------+---------------+---------+----------------------+----------------------+--------------------+
1 row in set (0.01 sec)

mysql> 

 

 查看存儲例程創建語句

mysql> show create procedure create_student;
+----------------+-----------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+--------------------+
| Procedure      | sql_mode                                                                                                              | Create Procedure                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             | character_set_client | collation_connection | Database Collation |
+----------------+-----------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+--------------------+
| create_student | ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION | CREATE DEFINER=`root`@`%` PROCEDURE `create_student`(OUT new_stuid INT,IN new_name VARCHAR(10),IN birth date,IN addr VARCHAR(50),IN gender VARCHAR(10),IN sub_jct VARCHAR(10))
BEGIN
    /*為new_stuid聲明變量*/
    DECLARE new_stuid int;
    DECLARE stu_sex int;
    select max(stuid) into new_stuid from tb_student2;
    set new_stuid = new_stuid +1;

    case stu_sex
    WHEN gender='男生' THEN SET stu_sex=0;
    WHEN gender='女生' THEN SET stu_sex=1;
    else set stu_sex=2;
    END case;

    /*插入數據到tb_student2*/
    insert INTO tb_student2(stuid,stuname,stusex,stubirth,stuaddr,collid) VALUES(new_stuid,new_name,stu_sex,birth,addr,2);



END               | utf8                 | utf8_general_ci      | utf8_bin           |
+----------------+-----------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+--------------------+
1 row in set (0.00 sec)

mysql> show create function create_student_function;
+-------------------------+-----------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+--------------------+
| Function                | sql_mode                                                                                                              | Create Function                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  | character_set_client | collation_connection | Database Collation |
+-------------------------+-----------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+--------------------+
| create_student_function | ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION | CREATE DEFINER=`root`@`%` FUNCTION `create_student_function`(new_name VARCHAR(10),birth date,addr VARCHAR(50),gender VARCHAR(10),sub_jct VARCHAR(10)) RETURNS int(11)
BEGIN
    /*為new_stuid聲明變量*/
    DECLARE new_stuid int;
    DECLARE stu_sex int;
    select max(stuid) into new_stuid from tb_student2;
    set new_stuid = new_stuid +1;

    case stu_sex
    WHEN gender='男生' THEN SET stu_sex=0;
    WHEN gender='女生' THEN SET stu_sex=1;
    else set stu_sex=2;
    END case;

    /*插入數據到tb_student2*/
    insert INTO tb_student2(stuid,stuname,stusex,stubirth,stuaddr,collid) VALUES(new_stuid,new_name,stu_sex,birth,addr,2);
    
    RETURN new_stuid;



END               | utf8                 | utf8_general_ci      | utf8_bin           |
+-------------------------+-----------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+--------------------+
1 row in set (0.00 sec)

mysql> 

存儲例程刪除

mysql> drop function create_student_function;
Query OK, 0 rows affected (0.02 sec)

mysql> show function status like '%create%';
Empty set (0.00 sec)

mysql> drop procedure create_student;
Query OK, 0 rows affected (0.03 sec)

mysql> show procedure status like '%create_student%';
Empty set (0.00 sec)

mysql> 

 • 標簽label可以加在begin…end語句以及loop, repeat和while語句

• 語句中通過iterate和leave來控制流程,iterate表示返回指定標簽位置,leave表示跳出標簽

 

使用label標簽

drop PROCEDURE if EXISTS test_procedure;
delimiter //
CREATE procedure test_procedure(in p1 int,out p2 int)
BEGIN
    label1:LOOP
    set p1 = p1 + 1;
    if p1 < 10 then ITERATE label1;END if;
    LEAVE label1;
    END LOOP label1;
    set p2=p1;
    END;
//

調試下:

mysql> call test_procedure(5,@p2);
Query OK, 0 rows affected (0.00 sec)

mysql> select @p2;
+------+
| @p2  |
+------+
|   10 |
+------+
1 row in set (0.00 sec)

mysql> 
 
Declare語句
• Declare語句通常用來聲明本地變量、游標、條件或者handler
• Declare語句只允許出現在begin … end語句中而且必須出現在第一行
• Declare的順序也有要求,通常是先聲明本地變量,再是游標,然后是條件和handler
 
存儲過程中的變量
• 本地變量可以通過declare語句進行聲明
• 聲明后的變量可以通過select … into var_list進行賦值,或者通過set語句賦值,或者通過定義游標並使用fetch … into var_list賦值
• 通過declare聲明變量方法

• 使用default指定變量的默認值,如果沒有指定默認值則初始值為NULL

• Type指明該變量的數據類型
• 聲明的變量作用范圍為被聲明的begin … end語句塊之間
• 聲明的變量和被引用的數據表中的字段名要區分開來

變量聲明在上面的例子里用到了,游標后面學到再寫。

 

 查看數據庫中已創建的存儲過程和函數:

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM