Mysql的存儲過程總結


一. 存儲過程的定義:

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

. 存儲過程的優點:

  • 簡化應用開發人員的工作。當用不同語言編寫多客戶應用程序,或多客戶應用程序在不同平台上運行且需要執行相同的數據庫操作之時。
  • 增強安全性。比如,銀行對所有普通操作使用存儲程序。這提供一個堅固而安全的環境,程序可以確保每一個操作都被妥善記入日志。在這樣一個設置中,應用程序和用戶不可能直接訪問數據庫表,但是僅可以執行指定的存儲程序。
  • 減少數據在數據庫和應用服務器之間的傳輸。

三.存儲過程的權限

  • 使用權限:
    ALTER ROUTINE 編輯或刪除存儲過程
   CREATE ROUTINE 建立存儲過程
    EXECUTE 運行存儲過程
    CREATE PROCEDURE p() SQL SECURITY INVOKER創建存儲過程中有一個特征子句可以讓存儲過程使用運行者的權限
    CREATE PROCEDURE p() SQL SECURITY DEFINER 默認值

四. 存儲過程的創建

 
  CREATE PROCEDURE sp_name ([proc_parameter[,...]])   
        [characteristic ...] routine_body  
  默認地,子程序與當前數據庫關聯。要明確地把子程序與一個給定數據庫關聯起來,可以在創建子程序的時候指定其名字為db_name.sp_name。
   sp_name 存儲過程的名字proc_parameter指定參數為IN, OUT,或INOUTcharacteristic 特征routine_body 包含合法的SQL過程語句。
  in 把數據從外部傳遞給存儲過程
  out 從存儲過程內部返回值給外部使用者
  inout  把數據傳遞給存儲過程和將存儲過程的返回值傳遞給外部使用者
  示例:
 
  CREATE PROCEDURE sp_test      /* 存儲過程名 */(IN inparms INT,OUT outparams varchar(32))

五. 存儲過程的刪除

  DROP PROCEDURE  [IF EXISTS] sp_name
    這個語句被用來移除一個存儲程序或函數。即,從服務器移除一個制定的子程序。在MySQL 5.1中,你必須有ALTER ROUTINE權限才可用此子程序。這個權限被自動授予子程序的創建者。IF EXISTS 子句是一個MySQL的擴展。如果程序或函數不存在,它防止發生錯誤。示例:DROP PROCEDURE IF EXISTS `Proc_Notify_UserfavDiscount_Mail2`$$

六. 存儲過程的狀態

  SHOW  PROCEDURE  STATUS ;顯示數據庫中所有存儲的存儲過程基本信息
 
  show create procedure procedure_name;顯示某一個存儲過程的創建語句
delimiter //			 /*改變輸入結束符*/
DROP PROCEDURE IF EXISTS sp_test //
CREATE PROCEDURE sp_test                                         /* 存儲過程名 */
(IN inparms INT,OUT outparams varchar(32))                         /* 輸入參數 */
BEGIN                                                           /* 語句塊頭 */
     DECLARE var CHAR(10);                                      /* 變量聲明 */
     DECLARE num int;
     IF inparms = 1 THEN                                         /* IF條件開始*/
         SET var = 'hello';                                        /* 賦值 */
     ELSE
        SET var = 'world';
     END IF;                                                     /* IF結束 */
     INSERT INTO t1 VALUES (var);                                /* SQL語句 */
     select count(*) from t1 into num;
     SELECT name FROM t1 LIMIT num, 1 INTO outparams;
END
//
delimiter ;
 call sp_test(1, @out);
Select @out;
事先創建表
create table t1(id int not null auto_increment,name varchar(45),primary key pk_id (id));

七. 存儲過程的變量

  聲明變量:
  DECLARE var_name[,...] type [DEFAULT value]     → 這個語句被用來聲明局部變量。如果要給變量提供一個默認值,需要  包含一個DEFAULT子句。值可以被指定為一個表達式,不需要為一個常  數。如果沒有DEFAULT子句,初始值為NULL。    → 局部變量的作用范圍在它被聲明的BEGIN ... END塊內。示例:DECLARE fromDate DATETIMEDECLARE nHour    INTDECLARE v_exit INT DEFAULT 0

八. 變量賦值

  變量賦值,可以直接賦值,或者通過查詢賦值
  語句:
  SET var_name = expr [, var_name = expr] ...select col_name into var_name[,...]  table_expr 
  示例:SET nowDate=NOW();SET a.fanli_discount = b.max_fanli;select count(*) into num  from table1 where price=100;

九. BEGIN...END復合語句

  [begin_label:] BEGIN      [statement_list] END [end_label] 
  存儲子程序可以使用BEGIN ... END復合語句來包含多個語句。statement_list 代表一個或多個語句的列表。statement_list之內每個語句都必須用分號(;)來結尾。   復合語句可以被標記。除非begin_label存在,否則end_label不能被給出,並且如果二者都存在,他們必須是同樣的。   使用多重語句需要客戶端能發送包含語句定界符;的查詢字符串。這個符號在命令行客戶端被用delimiter命令來處理。改變查詢結尾定界符;(比如改變為//)使得; 可被用在子程序體中。舉例:
DELIMITER //
CREATE PROCEDURE p1(IN parameter1 INT)
      BEGIN
      DECLARE variable1 INT;
      SET variable1 = parameter1 + 1;
      IF variable1 = 0 THEN
          INSERT INTO t VALUES (17);
      END IF;
      IF parameter1 = 0 THEN
          UPDATE t SET s1 = s1 + 1;
      ELSE
          UPDATE t SET s1 = s1 + 2;
      END IF;
END //
DELIMITER ;

十. 流程控制

  IF語句
      IF search_condition THEN statement_list         [ELSEIF search_condition THEN statement_list] ...        [ELSE statement_list]      END IF 
   IF實現了一個基本的條件構造。如search_condition求值為真,相應的SQL語句列表被執行。如果沒有search_condition匹配,在ELSE子句里的語句列表被執行。
  statement_list可以包括一個或多個語句。

十一. CASE語句

   CASE case_value       WHEN when_value THEN statement_list         [WHEN when_value THEN statement_list] ...         [ELSE statement_list]  END CASEOr:        CASE       WHEN search_condition THEN statement_list         [WHEN search_condition THEN statement_list] ...         [ELSE statement_list]  END CASE
  存儲程序的CASE語句實現一個復雜的條件構造。如果search_condition 求值為真,相應的SQL被執行。如果沒有搜索條件匹配,在ELSE子句里的語句被執行。
   示例:
delimiter //CREATE PROCEDURE p2 (IN parameter1 INT)BEGIN     DECLARE variable1 INT;     SET variable1 = parameter1 + 1;     CASE variable1          WHEN 0 THEN INSERT INTO t  VALUES (17);          WHEN 1 THEN INSERT INTO t   VALUES (18);          ELSE INSERT INTO t VALUES (19);     END CASE;END// 

十二. 循環語句

WHILE … END WHILE示例:delimiter //CREATE PROCEDURE p4 ()BEGIN       DECLARE v INT;       SET v = 0;       WHILE v < 5 DO           INSERT INTO t VALUES (v);           SET v = v + 1;      END WHILE;END //
 
LOOP … END LOOP示例:CREATE PROCEDURE p5 ()BEGIN     DECLARE v INT;     SET v = 0;     loop_label: LOOP         INSERT INTO t VALUES (v);         SET v = v + 1;         IF v >= 5 THEN             LEAVE loop_label;         END IF;    END LOOP;END //[begin_label:] LOOP         statement_listEND LOOP [end_label]LOOP允許某特定語句或語句群的重復執行,實現一個簡單的循環構造。在循環內的語句一直重復直到循環被退出,退出通常伴隨着一個LEAVE 語句。

十三. 補充:迭代(ITERATE)語句

CREATE PROCEDURE p7 ()BEGIN     DECLARE v INT;     SET v = 0;     loop_label: LOOP         IF v = 3 THEN             SET v = v + 1;             ITERATE loop_label;         END IF;         INSERT INTO t VALUES (v);         SET v = v + 1;         IF v >= 5 THEN             LEAVE loop_label;         END IF;     END LOOP;END //

十四. 注釋語法:

mysql存儲過程可使用兩種風格的注釋雙模杠:--,該風格一般用於單行注釋c風格:/* 注釋內容 */, 一般用於多行注釋
 
 
DELIMITER $$

USE `51fanli_cang`$$

DROP PROCEDURE IF EXISTS `Proc_Notify_UserfavDiscount_Mail2`$$

CREATE DEFINER=`root`@`%` PROCEDURE `Proc_Notify_UserfavDiscount_Mail2`(IN latestPushTime DATETIME)
BEGIN
DROP TEMPORARY TABLE IF EXISTS tmp_Userfav_Discount_Cnt;
CREATE TEMPORARY TABLE tmp_Userfav_Discount_Cnt
	AS
    SELECT
        a.user_id,
        COUNT(a.id) COUNT,
        ROUND(SUM(a.price) - SUM(b.pricenow), 2) diffprice
    FROM fav_userfav a
        INNER JOIN fav_product b
            ON a.product_id = b.id
    WHERE a.is_del = 0
        AND a.price_flg = 2
        AND a.in_buy = 0
        AND b.pricedown_time >= latestPushTime
    GROUP BY a.user_id;
   SELECT user_id,user_name,user_email,topic_title,link_pic,price,link_value,source_title,pricenow,shop_id,source_pic,COUNT,diffprice,rank FROM (
    SELECT user_id,user_name,user_email,topic_title,link_pic,price,link_value,source_title,pricenow,shop_id,source_pic,COUNT,diffprice,@rownum:=@rownum+1,
    IF(@pdept=heyf_tmp.user_id,@rank:=@rank+1,@rank:=1) AS rank,  
    @pdept:=heyf_tmp.user_id FROM (
    SELECT a.user_id ,a.topic_title,a.link_pic,a.price,b.link_value,b.source_title,b.pricenow,b.shop_id,b.source_pic,c.count,c.diffprice,d.user_name,d.user_email FROM fav_userfav a INNER JOIN fav_product b ON  a.product_id=b.id INNER JOIN 
	tmp_Userfav_Discount_Cnt c ON a.user_id=c.user_id INNER JOIN fav_user d ON d.user_id = c.user_id
    WHERE  a.is_del = 0 AND a.price_flg = 2 AND a.in_buy = 0 AND d.user_email IS NOT NULL
    ORDER BY a.user_id,b.pricedown_time,a.price - b.pricenow DESC 
    ) heyf_tmp ,(SELECT @rownum :=0 , @pdept := NULL ,@rank:=0) a ) result  
    WHERE rank<=5;
END$$

DELIMITER ;

 


免責聲明!

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



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