本人在最近的項目開發中常用到存儲過程(PROCEDURE
),因此想經過本文借用一個簡單示例來分享一個基礎的存儲過程(本文中的面試題目僅僅只是起到一個引導做用,以方便理解示例中的存儲過程)。面試
假設表card_info
裏面有下列字段:
ID
(表id) card_num
(卡號) card_balance
(卡餘額) card_jifen
(卡積分)
1,如須要將卡號的第3-6位爲5432的會員卡,加200塊錢的SQL命令;
2,如須要將一樣知足上述條件的卡,先扣1000積分,以後再加200塊錢,且積分不足1000時不操做,最後還需返回執行命令的卡數量。sql
-- 建立表結構:
DROP TABLE IF EXISTS card_info;
CREATE TABLE card_info (
id VARCHAR(32) NOT NULL COMMENT 'ID',
card_num VARCHAR(10) NOT NULL COMMENT '卡號',
card_balance DOUBLE(10,2) DEFAULT 0 COMMENT '卡餘額',
card_jifen INT(10) DEFAULT 0 COMMENT '卡積分',
PRIMARY KEY (id)
) ENGINE = INNODB DEFAULT CHARSET = utf8;
複製代碼
-- 插入示例數據:
INSERT INTO card_info(id, card_num, card_balance, card_jifen) VALUES(REPLACE(UUID(),'-',''), '0123456789', 100, 100);
INSERT INTO card_info(id, card_num, card_balance, card_jifen) VALUES(REPLACE(UUID(),'-',''), '0154326789', 0, 1000);
INSERT INTO card_info(id, card_num, card_balance, card_jifen) VALUES(REPLACE(UUID(),'-',''), '0154329876', 0, 2000);
複製代碼
一、使用通常SQL語句:spa
1.UPDATE card_info SET card_balance = card_balance + 200 WHERE SUBSTR(card_num FROM 3 FOR 4) = '5432';
複製代碼
2.UPDATE card_info SET card_balance = card_balance + 200, card_jifen = card_jifen - 1000 WHERE SUBSTR(card_num FROM 3 FOR 4) = '5432' AND card_jifen >= 1000;
複製代碼
二、使用存儲過程:code
第一步:建立存儲過程:server
DROP PROCEDURE IF EXISTS test_proc;
DELIMITER // -- 定義結束符,Mysql默認結束符';'
CREATE PROCEDURE test_proc (IN param VARCHAR(32), OUT result INTEGER(10)) -- 輸入輸出參數(IN\OUT\INOUT)
BEGIN
-- DECLARE定義變量
DECLARE cardId, cardNum VARCHAR(32);
DECLARE cardBalance, cardJifen DOUBLE(10,2);
-- 定義循環結束標記
DECLARE flag INT DEFAULT TRUE;
-- 定義遊標
DECLARE cardInfo CURSOR FOR SELECT id, card_num, card_balance, card_jifen FROM card_info WHERE SUBSTR(card_num FROM 3 FOR 4) = param;
-- 將結束標記綁定到遊標(Sql Server使用@@FETCH_STATUS)
DECLARE CONTINUE HANDLER FOR NOT FOUND SET flag = FALSE;
SET result = 0;
-- 打開遊標
OPEN cardInfo;
-- 從遊標中取值,交給變量
FETCH cardInfo INTO cardId, cardNum, cardBalance, cardJifen;
-- 開始循環
WHILE flag DO
IF cardJifen >= 1000 THEN
SET result = result +1;
UPDATE card_info SET card_jifen = cardJifen - 1000, card_balance = cardBalance + 200 WHERE ID = cardId;
END IF;
-- 從遊標中取下一組值,交給變量
FETCH cardInfo INTO cardId, cardNum, cardBalance, cardJifen;
END WHILE;
-- 關閉遊標,Sql server釋放遊標(DEALLOCATE)
CLOSE cardInfo;
END;
// -- 整個過程結束
DELIMITER ; -- 將結束符改回默認
複製代碼
第二步:調用存儲過程:開發
-- 定義參數和結果變量,調用存儲過程
SET @param = '5432';
CALL test_proc(@param, @result);
SELECT @result;
複製代碼
注意:Mysql和Sql Server中的存儲過程略微不一樣,例如:Sql Server中從遊標取值(FETCH NEXT FROM * INTO
)時會有一個狀態@@TETCH_STATUS
,不須要手動定義結束標記和綁定到遊標的操做;Sql Server中在關閉遊標後還須要手動釋放遊標(DEALLOCATE *
)的操做。。。本文僅以Mysql爲例。class