一,語法:
create procedure 存儲過程名字()
(
[in|out|inout] 參數 datatype
)
begin
MySQL 語句;
end;
MySQL 存儲過程參數如果不顯式指定“in”、“out”、“inout”,則默認為“in”。習慣上,對于是“in” 的參數,我們都不會顯式指定。
二,規則
- 輸入參數例子,我們選擇了會話變量@x證明成功的將參數傳入了改變量.
mysql> CREATE PROCEDURE p2(p INT) SET @x = p ;//
Query OK, 0 rows affected (0.02 sec)
mysql> CALL p2(123)//
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT @x//
+------+
| @x |
+------+
| 123 |
+------+
1 row in set (0.01 sec)
- 輸出參數的例子,我們選擇會話變量@y去接收存儲過程p3
mysql> CREATE PROCEDURE p3(OUT p INT)
-> SET p = -5;//
Query OK, 0 rows affected (0.00 sec)
mysql> CALL p3(@y)//
Query OK, 0 rows affected (0.01 sec)
mysql> SELECT @y//
+------+
| @y |
+------+
| -5 |
+------+
1 row in set (0.00 sec)
MySQL 存儲過程名字后面的“()”是必須的,即使沒有一個參數,也需要“()”
MySQL 存儲過程參數,不能在參數名稱前加“@”,如:“@a int”。下面的創建存儲過程語法在 MySQL 中是錯誤的(在 SQL Server 中是正確的)。 MySQL 存儲過程中的變量,不需要在變量名字前加“@”,雖然 MySQL 客戶端用戶變量要加個“@”。
MySQL 存儲過程的參數不能指定默認值。
如果 MySQL 存儲過程中包含多條 MySQL 語句,則需要 begin end 關鍵字。
MySQL 存儲過程中的每條語句的末尾,都要加上分號 “;”
MySQL 存儲過程中的注釋:
/*
這是個
多行 MySQL 注釋。
*/
declare c int; -- 這是單行 MySQL 注釋 (注意 -- 后至少要有一個空格)
if a is null then # 這也是個單行 MySQL 注釋
set a = 0;
end if;
...
end;
- 不能在 MySQL 存儲過程中使用 “return” 關鍵字:
set c = a + b;
select c as sum;
/*
return c; -- 不能在 MySQL 存儲過程中使用。return 只能出現在函數中。
*/
end;
- 調用 MySQL 存儲過程時候,需要在過程名字后面加“()”,即使沒有一個參數,也需要“()”
call pr_no_param();
三,實例:
- 批量添加數據(預制原始券)
/*
* 預制原始券
-- @author: liangxifeng
-- @date : 2015-11-25
-- @param : int - @ticketCount - 要預制的券數量
-- @return: 成功返回:成功預制數量, 失敗:返回具體信息
-- @php調用: mysql_fetch_assoc(mysql_query("CALL initTicket(100)"));
*/
DELIMITER $$
DROP PROCEDURE IF EXISTS `initTicket` $$
CREATE PROCEDURE initTicket( IN ticketCount INT )
BEGIN
DECLARE i INT DEFAULT 0; -- 計數器
DECLARE returnMsg VARCHAR(50) DEFAULT ''; -- 返回值信息
DECLARE rowCount int DEFAULT 0; -- 操作sql的時候影響行數
IF ticketCount >= 10000 || ticketCount=0 THEN
SET returnMsg = 'paramError';
SELECT returnMsg;
ELSE
outer_label:BEGIN
START TRANSACTION;
WHILE i < ticketCount DO
SET i=i+1;
INSERT INTO `ticket_main` (`ticket_status`,`ticket_add_time`) VALUES (0,now());
SELECT row_count() INTO rowCount;
IF rowCount<=0 THEN
LEAVE outer_label;
END IF;
END WHILE;
END outer_label; -- 只要是在outer_label代碼塊內 任意位置 Leave outer_label,那么Leave后的代碼將不再執行
IF i=ticketCount THEN
COMMIT;
SET returnMsg = i;
ELSE
ROLLBACK;
SET returnMsg = 'error';
END IF;
SELECT returnMsg;
END IF;
END $$
DELIMITER ;