刪除存儲過程
存儲過程在創建之后,被保存在服務器上以供使用,直至被刪除。刪除命令(類似于第21章所介紹的語句)從服務器中刪除存儲過程。為刪除剛創建的存儲過程,可使用以下語句:
輸入:
drop?procedure?productpricing;
分析:這條語句刪除剛創建的存儲過程。請注意沒有使用后面的 () ,只給出存儲過程名。
僅當存在時刪除 如果指定的過程不存在,則 DROP PROCEDURE將產生一個錯誤。當過程存在想刪除它時(如果過程不存在也不產生錯誤)可使用 DROP PROCEDURE IF EXISTS。
使用參數
productpricing 只是一個簡單的存儲過程,它簡單地顯示 SELECT 語句的結果。一般,存儲過程并不顯示結果,而是把結果返回給你指定的變量。
變量(variable)內存中一個特定的位置,用來臨時存儲數據。以下是 productpricing 的修改版本(如果不先刪除此存儲過程,則不能再次創建它):
輸入:
create?procedure?productpricing( out?pl?decimal(8,2), out?ph?decimal(8,2), out?pa?decimal(8,2) ) begin select?min(prod_price)?into?pl?from?products; select?max(prod_price)?into?ph?from?products; select?avg(prod_price)?into?pa?from?products; end;
分析:此存儲過程接受3個參數: pl 存儲產品最低價格, ph 存儲產品最高價格, pa 存儲產品平均價格。每個參數必須具有指定的類型,這里使用十進制值。關鍵字 OUT 指出相應的參數用來從存儲過程傳出一個值(返回給調用者)。MySQL支持 IN (傳遞給存儲過程)、 OUT (從存儲過程傳出,如這里所用)和 INOUT (對存儲過程傳入和傳出)類型的參數。存儲過程的代碼位于 BEGIN 和 END 語句內,如前所見,它們是一系列SELECT 語句,用來檢索值,然后保存到相應的變量(通過指定 INTO 關鍵字)。
參數的數據類型 存儲過程的參數允許的數據類型與表中使用的數據類型相同。附錄D列出了這些類型。
注意,記錄集不是允許的類型,因此,不能通過一個參數返回多個行和列。這就是前面的例子為什么要使用3個參數(和3條 SELECT 語句)的原因。為調用此修改過的存儲過程,必須指定3個變量名,如下所示:
輸入:
call?productpricing(@price?low, @pricehigh, @priceaverage);
分析:由于此存儲過程要求3個參數,因此必須正好傳遞3個參數,不多也不少。所以,這條 CALL 語句給出3個參數。它們是存儲過程將保存結果的3個變量的名字。
變量名 所有MySQL變量都必須以 @ 開始。
在調用時,這條語句并不顯示任何數據。它返回以后可以顯示(或在其他處理中使用)的變量。為了顯示檢索出的產品平均價格,可如下進行:
輸入:
select?@priceaverage;
輸出:
為了獲得3個值,可使用以下語句:
輸入:
select?@pricehigh,@pricrlow,@priceaverage;
輸出:
下面是另外一個例子,這次使用 IN 和 OUT 參數。 ordertotal 接受訂單
號并返回該訂單的合計:
輸入:
create?procedure?ordertotal( in?onumber?int, out?ototal?decimal(8,2) ) begin select?sum(item_price*quantity)?from?orderitems?where?order_num?=?onumber?into?ototal; end;
分析:onumber 定義為 IN ,因為訂單號被傳入存儲過程。 ototal 定義為 OUT ,因為要從存儲過程返回合計。 SELECT 語句使用這兩個參數, WHERE 子句使用 onumber 選擇正確的行, INTO 使用 ototal 存儲計算出來的合計。
為調用這個新存儲過程,可使用以下語句:
輸入:
call?ordertotal(20005,@total);
分析:必須給 ordertotal 傳遞兩個參數;第一個參數為訂單號,第二個參數為包含計算出來的合計的變量名。為了顯示此合計,可如下進行:
輸入:
select?@total;
輸出:
分析:@total 已由 ordertotal 的 CALL 語句填寫, SELECT 顯示它包含的值。為了得到另一個訂單的合計顯示,需要再次調用存儲過程,然后重新顯示變量:
輸入:
call?ordertotal(20009,@total); select?@total;