詳解MariaDB數據庫的存儲過程


1.什么是存儲過程

很多時候,SQL語句都是針對一個或多個表的單條語句。但是也有時候有的查詢語句需要進行多次聯表查詢才能完成,此時就需要用到存儲過程了。

存儲過程(Stored Procedure)是在大型數據庫系統中,一組為了完成特定功能的SQL語句集,存儲在數據庫中經過第一次編譯后,再次調用不需要再次編譯。用戶通過指定存儲過程的名字並給出參數(如果該存儲過程帶有參數)來執行它。

存儲過程是數據庫中的一個重要對象,任何一個設計良好的數據庫應用程序都應該用到存儲過程。

2.為什么要使用存儲過程

1.存儲過程增強了SQL語言的功能和靈活性。存儲過程可以用流程控制語句編寫,有很強的靈活性,可以完成復雜的判斷和較復雜的運算。
2.存儲過程允許標准組件是編程。存儲過程被創建后,可以在程序中被多次調用,而不必重新編寫該存儲過程的SQL語句。而且數據庫專業人員可以隨時對存儲過程進行修改,對應用程序源代碼毫無影響。
3.存儲過程能實現較快的執行速度。如果某一操作包含大量的Transaction-SQL代碼或分別被多次執行,那么存儲過程要比批處理的執行速度快很多。因為存儲過程是預編譯的。在首次運行一個存儲過程時查詢,優化器對其進行分析優化,並且給出最終被存儲在系統表中的執行計划。而批處理的Transaction-SQL語句在每次運行時都要進行編譯和優化,速度相對要慢一些。
4.存儲過程能過減少網絡流量。針對同一個數據庫對象的操作(如查詢、修改),如果這一操作所涉及的Transaction-SQL語句被組織程存儲過程,那么當在客戶計算機上調用該存儲過程時,網絡中傳送的只是該調用語句,從而大大增加了網絡流量並降低了網絡負載。
5.存儲過程可被作為一種安全機制來充分利用。系統管理員通過執行某一存儲過程的權限進行限制,能夠實現對相應的數據的訪問權限的限制,避免了非授權用戶對數據的訪問,保證了數據的安全。

3.定義存儲過程

語法:

create procedure 過程名(參數1,參數2....)
begin 
	sql語句;
end

創建存儲過程之前我們必須修改mysql語句默認結束符;

3.1 使用delimiter可以修改執行符號

DELIMITER是分割符的意思,因為MySQL默認以";"為分隔符,如果我們沒有聲明分割符,那么編譯器會把存儲過程當成SQL語句進行處理,則存儲過程的編譯過程會報錯。

所以要事先用DELIMITER關鍵字申明當前段分隔符,這樣MySQL才會將";"當做存儲過程中的代碼,不會執行這些代碼,用完了之后要把分隔符還原。

例子:

# delimiter 新執行符號
MariaDB [book]> delimiter %		# 使用delimter后,每條SQL語句的結束符就變為%
MariaDB [book]> create procedure selCg()
    -> begin
    -> select * from category;
    -> end %
Query OK, 0 rows affected (0.08 sec)

4.調用存儲過程

語法:

call 過程名(參數1,參數2);

例子:

MariaDB [book]> call selCg() %			# 調用上面定義的存儲過程 selCg
+---------+---------------+
| bTypeId | bTypeName     |
+---------+---------------+
|       1 | windows應用   |
|       2 | 網站          |
|       4 | linux學習     |
|       5 | Delphi學習    |
|       6 | 黑客          |
|       7 | 網絡技術      |
|       8 | 安全          |
|       9 | 平面          |
|      10 | AutoCAD技術   |
+---------+---------------+
9 rows in set (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

MariaDB [book]> delimiter ;				# 使用delimter把SQL語句的結束符改回原來的';'

5.存儲過程參數類型

5.1 In參數

特點:讀取外部變量值,且有效范圍僅限存儲過程內部

例子一:

MariaDB [book]> delimiter //	# 使用delimter把SQL語句的結束符改為的'//'
MariaDB [book]> create procedure pin(in p_in int)		# 定義存儲過程,讀取外部的整型變量p_in
    -> begin
    -> select p_in;				# 讀取參數中傳遞的p_in的值,p_in來自存儲過程外部
    -> set p_in = 2;			# 更改參數p_in的值為2
    -> select p_in;				# 再次查詢參數p_in的值
    -> end//
Query OK, 0 rows affected (0.01 sec)

MariaDB [book]> delimiter ;				# 使用delimter把SQL語句的結束符改回原來的';'
MariaDB [book]> set @num = 1;			# 在console中設定一個變量num,值為1
Query OK, 0 rows affected (0.01 sec)

MariaDB [book]> call pin(@num);			# 把前面定義的變量num做為參數,調用存儲過程pin
+------+								# 第一次查詢到的值為1,經過存儲過程為參數重新賦值,第二次查詢到的值為2
| p_in |
+------+
|    1 |
+------+
1 row in set (0.01 sec)

+------+
| p_in |
+------+
|    2 |
+------+
1 row in set (0.01 sec)

Query OK, 0 rows affected (0.01 sec)

MariaDB [book]> call pin(6);			# 再次調用存儲過程pin,傳入參數為整數6
+------+								# 同樣第一次查到的值為6,第二次查到的值改為2
| p_in |
+------+
|    6 |
+------+
1 row in set (0.00 sec)

+------+
| p_in |
+------+
|    2 |
+------+
1 row in set (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

MariaDB [book]> select @num;			# 在console中查詢num變量的值,仍為1,存儲過程的作用范圍只在存儲過程內部有效
+------+
| @num |
+------+
|    1 |
+------+
1 row in set (0.00 sec)

例子二:定義存儲過程 getOneBook,當輸入某書籍 id 后,可以調出對應書籍記錄

MariaDB [book]> delimiter //						# 修改SQL語句結束符為'//'
MariaDB [book]> create procedure get_book_by_id(in b int)	# 定義存儲過程get_book_by_id,傳入book的id,查詢對應book的信息記錄
    -> begin
    -> select * from books where bId=b;
    -> end//
Query OK, 0 rows affected (0.00 sec)

MariaDB [book]> delimiter ;				# 修改SQL語句結束符為';'

MariaDB [book]> call get_book_by_id(4);			# 查詢book的id為4的記錄
+-----+---------------------------------+---------+-----------------------+-------+------------+-----------+------------+
| bId | bName                           | bTypeId | publishing            | price | pubDate    | author    | ISBN       |
+-----+---------------------------------+---------+-----------------------+-------+------------+-----------+------------+
|   4 | pagemaker 7.0短期培訓教程       | 9       | 中國電力出版社        |    43 | 2005-01-01 | 孫利英    | 7121008947 |
+-----+---------------------------------+---------+-----------------------+-------+------------+-----------+------------+
1 row in set (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

MariaDB [book]> call get_book_by_id(9);			# 查詢book的id為9的記錄
+-----+---------------------------+---------+-----------------------+-------+------------+--------+------------+
| bId | bName                     | bTypeId | publishing            | price | pubDate    | author | ISBN       |
+-----+---------------------------+---------+-----------------------+-------+------------+--------+------------+
|   9 | Dreamweaver 4網頁制作     | 2       | 清華大學出版社        |    45 | 2004-04-01 | 黃宇   | 7505380796 |
+-----+---------------------------+---------+-----------------------+-------+------------+--------+------------+
1 row in set (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

5.2 Out參數

特點:不讀取外部變量值,在存儲過程執行完畢后保留新值

例子一:

MariaDB [book]> delimiter //

MariaDB [book]> create procedure pout(out p_out int)
    -> begin
    -> select p_out;
    -> set p_out=2;
    -> select p_out;
    -> end;
    -> //
Query OK, 0 rows affected (0.09 sec)

MariaDB [book]> delimiter ;
MariaDB [book]> set @out_num = 1;
Query OK, 0 rows affected (0.00 sec)

MariaDB [book]> call pout(@out_num);
+-------+
| p_out |
+-------+
|  NULL |
+-------+
1 row in set (0.00 sec)

+-------+
| p_out |
+-------+
|     2 |
+-------+
1 row in set (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

MariaDB [book]> set @num1=1;
Query OK, 0 rows affected (0.00 sec)

MariaDB [book]> call pout(@num1);
+-------+
| p_out |
+-------+
|  NULL |
+-------+
1 row in set (0.00 sec)

+-------+
| p_out |
+-------+
|     2 |
+-------+
1 row in set (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

例子二:

MariaDB [book]> delimiter //
MariaDB [book]> create procedure pout1(out p_out int)
    -> begin
    -> set p_outs=8;
    -> select p_outs;
    -> end;
    -> //
Query OK, 0 rows affected (0.00 sec)

MariaDB [book]> delimiter ;
MariaDB [book]> set @out_num1=1;
Query OK, 0 rows affected (0.00 sec)

MariaDB [book]> select @out_num1;
+-----------+
| @out_num1 |
+-----------+
|         1 |
+-----------+
1 row in set (0.00 sec)

MariaDB [book]> call pout1(@out_num1);
+-------+
| p_out |
+-------+
|     8 |
+-------+
1 row in set (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

MariaDB [book]> select @out_num1;
+-----------+
| @out_num1 |
+-----------+
|         8 |
+-----------+
1 row in set (0.00 sec)

不論你怎么賦值都是,存儲過程的執行結果都是8。

In傳入參數,是外部將值傳給存儲過程來使用的,而out傳出參數是為了講存儲過程的執行結果回傳給調用他的程序來使用的.

MariaDB [book]> delimiter //
MariaDB [book]> create procedure demo(out pa varchar(200))
    -> begin
    -> select bName into pa from books where bId=4;
    -> end//
Query OK, 0 rows affected (0.01 sec)

MariaDB [book]> delimiter ;
MariaDB [book]> call demo(@a);
Query OK, 1 row affected (0.07 sec)

MariaDB [book]> select @a;
+---------------------------------+
| @a                              |
+---------------------------------+
| pagemaker 7.0短期培訓教程       |
+---------------------------------+
1 row in set (0.00 sec)

MariaDB [book]> select * from books where bId=4;
+-----+---------------------------------+---------+-----------------------+-------+------------+-----------+------------+
| bId | bName                           | bTypeId | publishing            | price | pubDate    | author    | ISBN       |
+-----+---------------------------------+---------+-----------------------+-------+------------+-----------+------------+
|   4 | pagemaker 7.0短期培訓教程       | 9       | 中國電力出版社        |    43 | 2005-01-01 | 孫利英    | 7121008947 |
+-----+---------------------------------+---------+-----------------------+-------+------------+-----------+------------+
1 row in set (0.01 sec)

5.3 Inout參數

特點:讀取外部變量,在存儲過程執行完后保留新值<類似銀行存款>

MariaDB [book]> delimiter //
MariaDB [book]> create procedure p_in_out (inout p_inout_num int)
    -> begin
    -> select p_inout_num;
    -> set p_inout_num=100;
    -> select p_inout_num;
    -> end;
    -> //
Query OK, 0 rows affected (0.00 sec)

MariaDB [book]> delimiter ;
MariaDB [book]> set @num2=11;
Query OK, 0 rows affected (0.00 sec)

MariaDB [book]> call p_in_out(@num2);
+-------------+
| p_inout_num |
+-------------+
|          11 |
+-------------+
1 row in set (0.01 sec)

+-------------+
| p_inout_num |
+-------------+
|         100 |
+-------------+
1 row in set (0.01 sec)

Query OK, 0 rows affected (0.01 sec)

MariaDB [book]> select @num2;
+-------+
| @num2 |
+-------+
|   100 |
+-------+
1 row in set (0.00 sec)

5.4 不加參數的情況

如果在創建存儲過程時沒有指定參數類型,則需要在調用的時候指定參數值

MariaDB [book]> create table demo2(id int(11));
Query OK, 0 rows affected (0.06 sec)

MariaDB [book]> delimiter //
MariaDB [book]> create procedure insert_table(n1 int)
    -> begin
    -> set @x=0;
    -> repeat set @x=@x+1;
    -> insert into demo2 values(@x);
    -> until @x>n1
    -> end repeat;
    -> end;
    -> //
Query OK, 0 rows affected (0.00 sec)

MariaDB [book]> delimiter ;
MariaDB [book]> call insert_table(8);
Query OK, 1 row affected (0.05 sec)

MariaDB [book]> select * from demo2;
+------+
| id   |
+------+
|    1 |
|    2 |
|    3 |
|    4 |
|    5 |
|    6 |
|    7 |
|    8 |
|    9 |
+------+
9 rows in set (0.00 sec)

5.5 存儲過程變量的使用

MySQL中使用declare進行變量定義

變量定義

DECLARE variable_name [,variable_name...] datatype [DEFAULT value];

datatype為MySQL的數據類型,如:int, float, date, varchar(length)
變量賦值:

SET 變量名 = 表達式值 [,variable_name = expression ...]

變量賦值可以在不同的存儲過程中繼承

MariaDB [book]> delimiter //
MariaDB [book]> create procedure decl()
    -> begin
    -> declare name varchar(200);
    -> set name=(select bName from books where bId=6);
    -> select name;
    -> end//
Query OK, 0 rows affected (0.00 sec)

MariaDB [book]> delimiter ;
MariaDB [book]> call decl;
+------------------------------+
| name                         |
+------------------------------+
| Dreamweaver 4入門與提高      |
+------------------------------+
1 row in set (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

MariaDB [book]> select bName from books where bId=6;
+------------------------------+
| bName                        |
+------------------------------+
| Dreamweaver 4入門與提高      |
+------------------------------+
1 row in set (0.00 sec)

5.6 存儲過程語句的注釋

做過開發的都知道,寫注釋是個利人利己的事情。便於理解維護

MySQL注釋有兩種風格

“--“:單行注釋
“/*…..*/”:一般用於多行注釋

例子:

MariaDB [book]> delimiter //
MariaDB [book]> create procedure p1() -- procedure name is p1
    -> /* procedure body */
    -> /* start begin */
    -> begin
    -> declare name varchar(200);
    -> set name=(select bName from books where bId=6);
    -> select name;
    -> end//
Query OK, 0 rows affected (0.00 sec)

MariaDB [book]> delimiter ;
MariaDB [book]> call p1;
+------------------------------+
| name                         |
+------------------------------+
| Dreamweaver 4入門與提高      |
+------------------------------+
1 row in set (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

5.7 存儲過程流程控制語句

變量作用域:

內部的變量在其作用域范圍內享有更高的優先權,當執行到end變量時,內部變量消失,此時已經在其作用域外,變量不再可見了。因為在存儲過程外再也不能找到這個申明的變量,但是你可以通過out參數或者將其值指派給會話變量來保存其值。

例子:

MariaDB [book]> delimiter //
MariaDB [book]> create procedure proc2()
    -> begin
    -> declare x1 varchar(5) default "outer";
    -> begin
    -> declare x1 varchar(5) default "inner";
    -> select x1;
    -> end;
    -> select x1;
    -> end//
Query OK, 0 rows affected (0.01 sec)

MariaDB [book]> delimiter ;
MariaDB [book]> call proc2;
+-------+
| x1    |
+-------+
| inner |
+-------+
1 row in set (0.00 sec)

+-------+
| x1    |
+-------+
| outer |
+-------+
1 row in set (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

MariaDB [book]> select @x1;
+------+
| @x1  |
+------+
| NULL |
+------+
1 row in set (0.00 sec)

5.7.1 if-then -else條件語句

例子:

MariaDB [book]> select * from demo2;
Empty set (0.00 sec)

MariaDB [book]> delimiter //
MariaDB [book]> create procedure proc1(in args int)
    -> begin
    -> declare var int;
    -> set var = args + 1;
    -> if var = 0 then
    -> insert into demo2 values(17);
    -> end if;
    -> if args = 0 then
    -> update demo2 set id=id+1;
    -> else
    -> update demo2 set id=id+2;
    -> end if;
    -> end //
Query OK, 0 rows affected (0.01 sec)

MariaDB [book]> delimiter ;
MariaDB [book]> call proc1(2);
Query OK, 0 rows affected (0.02 sec)

MariaDB [book]> select * from demo2;
Empty set (0.00 sec)

MariaDB [book]> call proc1(-1);
Query OK, 1 row affected (0.01 sec)

MariaDB [book]> select * from demo2;
+------+
| id   |
+------+
|   19 |
+------+
1 row in set (0.00 sec)

5.7.2 case語句

例子:

MariaDB [book]> delimiter //
MariaDB [book]> create procedure proc3(in args int)
    -> begin
    -> declare var int;
    -> set var =args + 1;
    -> case var
    -> when 0 then
    -> insert into demo2 values(20);
    -> when 1 then
    -> insert into demo2 values(30);
    -> else
    -> insert into demo2 values(40);
    -> end case;
    -> end //
Query OK, 0 rows affected (0.00 sec)

MariaDB [book]> delimiter ;
MariaDB [book]> call proc3(1);
Query OK, 1 row affected (0.01 sec)

MariaDB [book]> select * from demo2;
+------+
| id   |
+------+
|   19 |
|   40 |
+------+
2 rows in set (0.01 sec)

MariaDB [book]> call proc3(6);
Query OK, 1 row affected (0.01 sec)

MariaDB [book]> select * from demo2;
+------+
| id   |
+------+
|   19 |
|   40 |
|   40 |
+------+
3 rows in set (0.00 sec)

5.7.3 while ···· end while循環語句

例子:

MariaDB [book]> delimiter //
MariaDB [book]> create procedure proc4()
    -> begin
    -> declare var int;
    -> set var=0;
    -> while var < 6 do
    -> insert into demo2 values(var);
    -> set var = var + 1;
    -> end while;
    -> end//
Query OK, 0 rows affected (0.01 sec)

MariaDB [book]> delimiter ;
MariaDB [book]> select * from demo2;
+------+
| id   |
+------+
|   19 |
|   40 |
|   40 |
+------+
3 rows in set (0.00 sec)

MariaDB [book]> call proc4;
Query OK, 1 row affected (0.03 sec)

MariaDB [book]> select * from demo2;
+------+
| id   |
+------+
|   19 |
|   40 |
|   40 |
|    0 |
|    1 |
|    2 |
|    3 |
|    4 |
|    5 |
+------+
9 rows in set (0.00 sec)

5.7.4 repeat···· end repeat

執行操作后檢查結果,而while則是執行前進行檢查。

例子:

MariaDB [book]> delimiter //
MariaDB [book]> create procedure proc5()
    -> begin
    -> declare v int;
    -> set v = 0;
    -> repeat
    -> insert into demo2 values(v);
    -> set v=v+1;
    -> until v> 5
    -> end repeat;
    -> end//
Query OK, 0 rows affected (0.00 sec)

MariaDB [book]> delimiter ;
MariaDB [book]> truncate table demo2;
Query OK, 0 rows affected (0.02 sec)

MariaDB [book]> select * from demo2;
Empty set (0.01 sec)

MariaDB [book]> call proc5;
Query OK, 1 row affected (0.05 sec)

MariaDB [book]> select * from demo2;
+------+
| id   |
+------+
|    0 |
|    1 |
|    2 |
|    3 |
|    4 |
|    5 |
+------+
6 rows in set (0.00 sec)

5.7.5 loop ·····end loop

loop循環不需要初始條件,這點和while 循環相似,同時和repeat循環一樣不需要結束條件, leave語句的意義是離開循環。

例子:

MariaDB [book]> delimiter //
MariaDB [book]> truncate table demo2//
Query OK, 0 rows affected (0.02 sec)

MariaDB [book]> create procedure proc6()
    -> begin
    -> declare v int;
    -> set v=0;
    -> loop_lable:loop
    -> insert into demo2 values(v);
    -> set v=v+1;
    -> if v>=5 then
    -> leave loop_lable;
    -> end if;
    -> end loop;
    -> end//
Query OK, 0 rows affected (0.00 sec)

MariaDB [book]> delimiter ;
MariaDB [book]> select * from demo2;
Empty set (0.00 sec)

MariaDB [book]> call proc6;
Query OK, 1 row affected (0.05 sec)

MariaDB [book]> select * from demo2;
+------+
| id   |
+------+
|    0 |
|    1 |
|    2 |
|    3 |
|    4 |
+------+
5 rows in set (0.00 sec)

5.7.6 LABLES 標號

標號可以用在begin repeat while 或者loop 語句前,語句標號只能在合法的語句前面使用。可以跳出循環,使運行指令達到復合語句的最后一步。

5.7.7 ITERATE迭代

通過引用復合語句的標號,來從新開始復合語句

例子:

MariaDB [book]> delimiter //
MariaDB [book]> create procedure proc7()
    -> begin
    -> declare v int;
    -> set v=0;
    -> loop_lable:loop
    -> if v =3 then
    -> set v=v+1;
    -> iterate loop_lable;
    -> end if;
    -> insert into demo2 values(v);
    -> set v=v+1;
    -> if v>=10 then
    -> leave loop_lable;
    -> end if;
    -> end loop;
    -> end //
Query OK, 0 rows affected (0.01 sec)

MariaDB [book]> truncate table demo2//
Query OK, 0 rows affected (0.01 sec)

MariaDB [book]> select * from demo2//
Empty set (0.00 sec)

MariaDB [book]> delimiter ;
MariaDB [book]> call proc7;
Query OK, 1 row affected (0.03 sec)

MariaDB [book]> select * from demo2;
+------+
| id   |
+------+
|    0 |
|    1 |
|    2 |
|    4 |
|    5 |
|    6 |
|    7 |
|    8 |
|    9 |
+------+
9 rows in set (0.00 sec)

6. 查看存儲過程

語法:

show create procedure 存儲過程名 \G

例子:

MariaDB [book]> show create procedure proc7 \G
*************************** 1. row ***************************
           Procedure: proc7
            sql_mode: 
    Create Procedure: CREATE DEFINER=`root`@`localhost` PROCEDURE `proc7`()
begin
declare v int;
set v=0;
loop_lable:loop
if v =3 then
set v=v+1;
iterate loop_lable;
end if;
insert into demo2 values(v);
set v=v+1;
if v>=10 then
leave loop_lable;
end if;
end loop;
end
character_set_client: utf8
collation_connection: utf8_unicode_ci
  Database Collation: utf8_general_ci
1 row in set (0.00 sec)

MariaDB [book]> show create procedure proc6 \G
*************************** 1. row ***************************
           Procedure: proc6
            sql_mode: 
    Create Procedure: CREATE DEFINER=`root`@`localhost` PROCEDURE `proc6`()
begin
declare v int;
set v=0;
loop_lable:loop
insert into demo2 values(v);
set v=v+1;
if v>=5 then
leave loop_lable;
end if;
end loop;
end
character_set_client: utf8
collation_connection: utf8_unicode_ci
  Database Collation: utf8_general_ci
1 row in set (0.01 sec)

7.查看存儲過程狀態

語法:

show procedure status \G  查看所有存儲過程

例子:

MariaDB [book]> show procedure status \G
*************************** 1. row ***************************
                  Db: book
                Name: decl
                Type: PROCEDURE
             Definer: root@localhost
            Modified: 2018-08-29 08:51:15
             Created: 2018-08-29 08:51:15
       Security_type: DEFINER
             Comment: 
character_set_client: utf8
collation_connection: utf8_unicode_ci
  Database Collation: utf8_general_ci
*************************** 2. row ***************************
                  Db: book
                Name: demo
                Type: PROCEDURE
             Definer: root@localhost
            Modified: 2018-08-29 08:42:24
             Created: 2018-08-29 08:42:24
       Security_type: DEFINER
             Comment: 
character_set_client: utf8
collation_connection: utf8_unicode_ci
  Database Collation: utf8_general_ci
*************************** 3. row ***************************
                  Db: book
                Name: get_book_by_id
                Type: PROCEDURE
             Definer: root@localhost
            Modified: 2018-08-29 08:09:44
             Created: 2018-08-29 08:09:44
       Security_type: DEFINER
             Comment: 
character_set_client: utf8
collation_connection: utf8_unicode_ci
  Database Collation: utf8_general_ci
16 rows in set (0.04 sec)


MariaDB [book]> show procedure status ;
+------+----------------+-----------+----------------+---------------------+---------------------+---------------+---------+----------------------+----------------------+--------------------+
| Db   | Name           | Type      | Definer        | Modified            | Created             | Security_type | Comment | character_set_client | collation_connection | Database Collation |
+------+----------------+-----------+----------------+---------------------+---------------------+---------------+---------+----------------------+----------------------+--------------------+
| book | decl           | PROCEDURE | root@localhost | 2018-08-29 08:51:15 | 2018-08-29 08:51:15 | DEFINER       |         | utf8                 | utf8_unicode_ci      | utf8_general_ci    |
| book | demo           | PROCEDURE | root@localhost | 2018-08-29 08:42:24 | 2018-08-29 08:42:24 | DEFINER       |         | utf8                 | utf8_unicode_ci      | utf8_general_ci    |
| book | get_book_by_id | PROCEDURE | root@localhost | 2018-08-29 08:09:44 | 2018-08-29 08:09:44 | DEFINER       |         | utf8                 | utf8_unicode_ci      | utf8_general_ci    |
| book | insert_table   | PROCEDURE | root@localhost | 2018-08-29 08:48:54 | 2018-08-29 08:48:54 | DEFINER       |         | utf8                 | utf8_unicode_ci      | utf8_general_ci    |
| book | pin            | PROCEDURE | root@localhost | 2018-08-29 08:07:00 | 2018-08-29 08:07:00 | DEFINER       |         | utf8                 | utf8_unicode_ci      | utf8_general_ci    |
| book | pout           | PROCEDURE | root@localhost | 2018-08-29 08:31:36 | 2018-08-29 08:31:36 | DEFINER       |         | utf8                 | utf8_unicode_ci      | utf8_general_ci    |
| book | pout1          | PROCEDURE | root@localhost | 2018-08-29 08:36:39 | 2018-08-29 08:36:39 | DEFINER       |         | utf8                 | utf8_unicode_ci      | utf8_general_ci    |
+------+----------------+-----------+----------------+---------------------+---------------------+---------------+---------+----------------------+----------------------+--------------------+
7 rows in set (0.02 sec)

7. 修改存儲過程:

使用alter語句修改存儲過程

語法:

ALTER {PROCEDURE | FUNCTION} sp_name [characteristic ...] 
characteristic: 
{ CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA } 
| SQL SECURITY { DEFINER | INVOKER } 
| COMMENT 'string'

參數說明:

sp_name參數表示存儲過程或函數的名稱
characteristic參數指定存儲函數的特性
CONTAINS SQL表示子程序包含SQL語句,但不包含讀或寫數據的語句;
NO SQL表示子程序中不包含SQL語句
READS SQL DATA表示子程序中包含讀數據的語句
MODIFIES SQL DATA表示子程序中包含寫數據的語句
SQL SECURITY { DEFINER | INVOKER }指明誰有權限來執行
DEFINER表示只有定義者自己才能夠執行
INVOKER表示調用者可以執行
COMMENT 'string'是注釋信息。

8.刪除存儲過程

方法一:

DROP PROCEDURE 存儲過程名

語法:

MariaDB [book]> drop procedure demo;
Query OK, 0 rows affected (0.00 sec)

方法二:

DROP PROCEDURE IF EXISTS 存儲過程名

這個語句被用來移除一個存儲程序。

需要注意的是:

不能在一個存儲過程中刪除另一個存儲過程,只能調用另一個存儲過程

9.存儲過程的缺點:

1)可移植性差
2)對於簡單的SQL語句,存儲過程沒什么優勢
3)如果存儲過程中不一定會減少網絡傳輸
4)如果只有一個用戶使用數據庫,那么存儲過程對安全也沒什么影響
5)團隊開發時需要先統一標准,否則后期維護成本大
6)在大並發量訪問的情況下,不宜寫過多涉及運算的存儲過程
7)業務邏輯復雜時,特別是涉及到對很大的表進行操作的時候,不如在前端先簡化業務邏輯


免責聲明!

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



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