MySQL存儲過程,並在.net中調用

MySQL 存儲過程是從 MySQL 5.0 開始增加的新功能。

存儲過程最主要優點是執行效率和SQL 代碼封裝。

相對於SQL Server和Oracle存儲過程寫法大體類似,不過有些特殊語法要注意。

最簡潔的語法結構如下:

DELIMITER $$ 
CREATE
    PROCEDURE `dbbook`.`test`()  //在dbbook數據中創建名爲test的存儲過程
    BEGIN

    END$$


DELIMITER ;


修改存儲過程:

DELIMITER $$


USE `benq_ebook`$$


DROP PROCEDURE IF EXISTS `user_buy_analyze`$$


CREATE DEFINER=`root`@`%` PROCEDURE `user_buy_analyze`(IN antype VARCHAR (10),IN datefrom VARCHAR (10),IN dateto VARCHAR (50))
BEGIN
  DECLARE sumuser INT ;
  IF antype!='rec'
  THEN
  
  SET datefrom= CONCAT(datefrom,' 00:00:00');
  SET dateto= CONCAT(dateto,' 23:59:59');
   SELECT 
         COUNT(*) INTO sumuser 
       FROM
         user_profile AS u 
       WHERE u.uid IN 
         (SELECT 
           lo.uid 
        FROM
          log_order AS lo 
        INNER JOIN log_order_book AS lob 
             ON lo.orderNo = lob.orderNo 
             AND lob.goods_type != '08'
             AND lob.b_pay_status=1
            AND lo.o_est_datetime BETWEEN datefrom AND dateto);
    END IF;  
  CASE
    antype -- 性別百分比
    WHEN 'sex' 
    THEN 
    BEGIN
      
      SELECT 
        CASE u.sex 
          WHEN 'F' 
          THEN N'女' 
          WHEN 'M' 
          THEN N'男' 
          ELSE N'其他' 
        END AS sex,
        u.sex  AS sexid,
        (COUNT(*) / sumuser)*100  AS sexpercent 
      FROM
        user_profile AS u 
      WHERE u.uid IN 
        (SELECT 
          lo.uid 
        FROM
          log_order AS lo 
         INNER JOIN log_order_book AS lob 
            ON lo.orderNo = lob.orderNo 
            AND lob.goods_type != '08'
            AND lob.b_pay_status=1
            AND lo.o_est_datetime BETWEEN datefrom AND dateto) 
      GROUP BY u.sex 
      ORDER BY u.sex ;
    END ;
    -- 婚姻百分比
    WHEN 'mar' 
    THEN     BEGIN

SELECT 
        CASE
          u.marriage 
          WHEN 1 
          THEN N'未婚' 
          WHEN 2 
          THEN N'已婚,無小孩' 
          WHEN 3
          THEN N'已婚,有小孩'
          ELSE N'其他' 
        END AS mar,
        IFNULL(u.marriage,0)  AS marid,
        (COUNT(*) / sumuser)*100 AS marpercent 
      FROM
        user_profile AS u 
      WHERE u.uid IN 
        (SELECT 
          lo.uid 
        FROM
          log_order AS lo 
          INNER JOIN log_order_book AS lob 
            ON lo.orderNo = lob.orderNo 
            AND lob.goods_type != '08'
             AND lob.b_pay_status=1
            AND lo.o_est_datetime BETWEEN datefrom AND dateto) 
      GROUP BY u.marriage 
      ORDER BY u.marriage ;
      
      END;
    -- 教育
    WHEN 'edu' 
    THEN 
    BEGIN
      SELECT 
        CASE
          u.education
          WHEN 1 
          THEN N'國中' 
          WHEN 2 
          THEN N'高中(職)' 
          WHEN 3
          THEN N'大學'
          WHEN 4
          THEN N'碩士'
          WHEN 5
         THEN N'博士'
          ELSE N'其他' 
        END AS edu,
        IFNULL(u.education,0) AS eduid,
        (COUNT(*)/ sumuser)*100 AS edupercent 
      FROM
        user_profile AS u 
      WHERE u.uid IN 
        (SELECT 
          lo.uid 
        FROM
          log_order AS lo 
          INNER JOIN log_order_book AS lob 
            ON lo.orderNo = lob.orderNo 
            AND lob.goods_type != '08'
             AND lob.b_pay_status=1
            AND lo.o_est_datetime BETWEEN datefrom AND dateto) 
      GROUP BY u.education 
      ORDER BY u.education;
    END ;
    
    -- 職業
    WHEN 'pro' 
    THEN 
    BEGIN
     SELECT 
        CASE
          u.profession
          WHEN 1 
          THEN N'學生' 
          WHEN 2 
          THEN N'科技業' 
          WHEN 3
          THEN N'服務業'
          WHEN 4
          THEN N'製造業'
          WHEN 5
          THEN N'批發零售'
           WHEN 6
          THEN N'文創' 
          WHEN 7
          THEN N'軍公教'
          WHEN 8
          THEN N'醫療'
          WHEN 9
          THEN N'其他'
         ELSE N'(其他)' 
        END AS pro,
        IFNULL(u.profession,0) AS proid,
        (COUNT(*)/ sumuser)*100 AS propercent 
      FROM
        user_profile AS u 
      WHERE u.uid IN 
        (SELECT 
          lo.uid 
        FROM
          log_order AS lo 
          INNER JOIN log_order_book AS lob 
            ON lo.orderNo = lob.orderNo 
            AND lob.goods_type != '08'
             AND lob.b_pay_status=1
            AND lo.o_est_datetime BETWEEN datefrom AND dateto) 
      GROUP BY u.profession 
      ORDER BY u.profession;
    END ;
    
    -- 購買的書種
    WHEN 'rec' 
    THEN 
    BEGIN
         
         SELECT 
 COUNT(c.class_name) INTO sumuser
FROM
 log_order_book AS lob 
 INNER JOIN log_order AS lo
   ON lo.orderNo = lob.orderNo 
 INNER JOIN book_class bc 
   ON lob.book_seq = bc.book_seq 
INNER JOIN class c 
   ON c.class_seq = bc.class_seq 
   AND lob.goods_type != '08' 
    AND lob.b_pay_status=1
   AND c.class_name IN (
     '商業理財',
     '文學小說',
     '藝術設計'
     '心靈養生',
     '休閒娛樂',
     '圖文漫畫')
     AND lo.o_est_datetime BETWEEN datefrom AND dateto;
     
 SELECT 
 c.class_name AS rec,
 IFNULL(c.class_seq,0) AS recid,
 (COUNT(c.class_name)/sumuser)*100 AS recpercent
FROM
 log_order_book AS lob 
 INNER JOIN log_order AS lo
   ON lo.orderNo = lob.orderNo 
 INNER JOIN book_class bc 
   ON lob.book_seq = bc.book_seq 
INNER JOIN class c 
   ON c.class_seq = bc.class_seq 
   AND lob.goods_type != '08' 
    AND lob.b_pay_status
   AND c.class_name IN (
     '商業理財',
     '文學小說',
     '藝術設計',
     '心靈養生',
     '休閒娛樂',
     '圖文漫畫')
     AND lo.o_est_datetime BETWEEN datefrom AND dateto
GROUP BY c.class_name;
    END ;
  END CASE ;
END$$


DELIMITER ;

 

調用存儲過程:

CALL user_buy_analyze('edu','2011-01-01','2012-09-21')

 

注意事項:

  1. MySQL 存儲過程參數如果不顯式指定“in”、“out”、“inout”,則默認爲“in”。習慣上,對於是“in” 的參數,我們都不會顯式指定。
  2. MySQL 存儲過程不需要在 procedure body 前面加 “as”。而 SQL Server 存儲過程必須加 “as” 關鍵字。 
  3. 不能在 MySQL 存儲過程中使用。return 只能出現在函數中。
  4. 如果 MySQL 存儲過程中包含多條 MySQL 語句,則需要 begin end; 關鍵字。 
  5. MySQL 存儲過程中的每條語句的末尾,都要加上分號 “;” 
  6. 調用 MySQL 存儲過程時候,需要在過程名字後面加“()”,即使沒有一個參數,也需要“()” 
  7. 因爲 MySQL 存儲過程參數沒有默認值,所以在調用 MySQL 存儲過程時候,不能省略參數。可以用 null 來替代。 
  8. MySQL 存儲過程中的變量,不需要在變量名字前加“@”,雖然 MySQL 客戶端用戶變量要加個“@”。 

 ASP.NET中訪問MySQL存儲過程:

using MySql.Data.MySqlClient;
using System.Data.SqlClient;


public DataSet GetDataSet(string type,string DateFrom,string DateTo)
        {
            string connection = eBookConnection.connectionMySql;
            MySqlConnection myCon = new MySqlConnection(eBookConnection.connectionMySql);
            myCon.Open();
            DataTable dt = new DataTable();
            try
            {
                MySqlDataAdapter command = new MySqlDataAdapter();
                DataSet ds = new DataSet();
                command.SelectCommand = new MySqlCommand();
                command.SelectCommand.Connection = myCon;
                command.SelectCommand.CommandText = "user_buy_analyze";
                command.SelectCommand.CommandType = CommandType.StoredProcedure;
                MySqlParameter antype_para = new MySqlParameter("?antype", MySqlDbType.VarChar, 10);//mysql的存儲過程參數是以?打頭的 
                MySqlParameter datefrom_para = new MySqlParameter("?datefrom", MySqlDbType.VarChar, 50);
                MySqlParameter dateto_para = new MySqlParameter("?dateto", MySqlDbType.VarChar, 50);
                antype_para.Value = type;
                datefrom_para.Value = DateFrom;
                dateto_para.Value = DateTo;
                command.SelectCommand.Parameters.Add(antype_para);
                command.SelectCommand.Parameters.Add(datefrom_para);
                command.SelectCommand.Parameters.Add(dateto_para);  
                command.Fill(ds);
                return ds;
            }
            catch (Exception e)
            {
                throw e;
            }
            finally
            {
                myCon.Close();
            }
        }


發佈了24 篇原創文章 · 獲贊 3 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章