參考:http://blog.csdn.net/qq_35246620/article/details/70823903
存儲過程
存儲過程簡稱過程,procedure
,是一種用來處理數據(增刪改)的方式。簡單點,我們也可以將其理解爲沒有返回值的函數。
創建過程
-- 基本語法
create procedure 過程名([參數列表])
begin
-- 過程體
end
- 1
- 2
- 3
- 4
- 5
如果我們定義的過程的過程體內僅含有一條語句,則可以省略begin
和end
。執行如下語句,進行測試:
-- 創建過程
create procedure pro()
select * from student;
- 1
- 2
- 3
如上圖所示,我們創建了一個名爲pro()
的過程,其目的就是爲了查詢student
表中的數據。但實際上,過程多用於處理數據,查詢並不多用。
查看過程
查看過程,基本語法爲:
show procedure status + [like 'pattern'];
查看過程的創建語句,基本語法爲:
show create procedure + 過程名;
調用過程
由於函數有返回值,因此我們可以用select
來調用函數。但是存儲過程沒有返回值,怎麼辦?實際上,對於存儲過程,有一個專門的調用關鍵字call
,調用過程的基本語法爲:
call + 過程名;
修改過程 & 刪除過程
過程只能先刪除後新增,不能修改。刪除過程的基本語法爲:
drop procedure + 過程名;
執行如下語句,進行測試:
-- 刪除過程
drop procedure pro;
-- 查看過程
show procedure status like 'pro'\G;
- 1
- 2
- 3
- 4
過程參數
函數的參數需要指定數據類型,過程比函數更加嚴格。過程有三種自己的參數類型,分別爲:
in
,數據只是從過程外部傳入給過程內部使用,可以是數值也可以是變量;out
,此參數只能傳遞變量,且變量指向的數據需要先清空然後才能進入過程內部,該引用供過程內部使用,過程結束後可以將變量的值傳遞給過程外部使用;inout
,此參數只能傳遞變量,該變量的值可以給過程內部使用,過程結束後可以變量的值傳遞給過程外部使用。
因此,過程定義的具體形式應該爲:
procedure 過程名(in 參數名字 參數類型, out 參數名字 參數類型, inout 參數名字 參數類型)
下面,我們定義一個簡單的過程,並調用過程。代碼如下:
delimiter $$
create procedure pro2(in var1 int, out var2 int, inout var3 int)
begin
-- 查看該過程傳入的三個變量
select var1, var2, var3;
end
$$
delimiter ;
-- 調用過程
call pro2(1,2,3);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
如上圖所示,過程pro2
創建成功。但是,在調用過程的時候出現錯誤,造成該錯誤的原因爲:過程的out
和inout
兩個參數只能接受變量,而我們傳遞了具體的數值,報錯也就在情理之中啦!接下來,執行如下語句,進行測試:
-- 設置全局變量
set @var1 = 1;
set @var2 = 2;
set @var3 = 3;
-- 調用過程
call pro2(@var1, @var2, @var3);
-- 查看變量
select @var1, @var2, @var3;
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
如上圖所示,在我們將變量傳遞給過程的時候,過程正常執行。此外,通過select
語句我們可以看到傳遞給out
類型參數的@var2
的值在經過過程處理之後,被置爲null
值啦,這也是符合out
類型參數的先清空後使用原則的。而且,由於out
和inout
只能接受變量作爲參數,因此在過程內部對out
和inout
傳入的變量的修改會影響到過程外部。在這裏,值得我們注意是:存儲過程對變量的操作是滯後的,即只有在過程結束的時候,纔會將過程內部修改的值賦值給外部傳入的對應的全局變量。執行如下語句,進行測試:
delimiter $$
create procedure pro3(in var1 int, out var2 int, inout var3 int)
begin
-- 查看該過程傳入的三個變量
select var1, var2, var3;
-- 修改局部變量
set var1 = 10;
set var2 = 20;
set var3 = 30;
-- 查看局部變量
select var1, var2, var3;
-- 查看全局變量
select @var1, @var2, @var3;
-- 修改全局變量
set @var1 = 'a';
set @var2 = 'b';
set @var3 = 'c';
-- 查看全局變量
select @var1, @var2, @var3;
end
$$
delimiter ;
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
-- 調用過程
call pro3(@var1, @var2, @var3);
-- 在過程結束後,查看全局變量
select @var1, @var2, @var3;
- 1
- 2
- 3
- 4
如上圖所示,存儲過程執行成功,且驗證了我們結論,即:在存儲過程沒有結束的時候,對傳入變量的修改並不會影響到對應的全局變量;只有在存儲過程結束後,纔會將對應的變量值賦值給out
和inout
類型的變量,而in
類型的變量不受影響。