存儲(chǔ)過程簡(jiǎn)介
存儲(chǔ)過程(Stored Procedure)是數(shù)據(jù)庫(kù)系統(tǒng)中,一組為了完成特定功能的SQL 語(yǔ)句集粥鞋,經(jīng)編譯后存儲(chǔ)在數(shù)據(jù)庫(kù)中,用戶通過指定存儲(chǔ)過程的名字并給出參數(shù)(如果該存儲(chǔ)過程帶有參數(shù))來執(zhí)行它瞄崇。在數(shù)據(jù)庫(kù)系統(tǒng)中呻粹,存儲(chǔ)過程和觸發(fā)器具有很重要的作用壕曼。無論是存儲(chǔ)過程還是觸發(fā)器,都是SQL 語(yǔ)句和流程控制語(yǔ)句的集合等浊。
存儲(chǔ)過程分類
1系統(tǒng)存儲(chǔ)過程
以sp_開頭,用來進(jìn)行系統(tǒng)的各項(xiàng)設(shè)定.取得信息.相關(guān)管理工作腮郊。
2本地存儲(chǔ)過程
用戶創(chuàng)建的存儲(chǔ)過程是由用戶創(chuàng)建并完成某一特定功能的存儲(chǔ)過程,這跟各種編程語(yǔ)言里用戶自己寫的函數(shù)非常類似筹燕。我們一般所說的存儲(chǔ)過程就是指本地存儲(chǔ)過程轧飞。今天我們重點(diǎn)介紹本地存儲(chǔ)過程,其他存儲(chǔ)過程了解即可撒踪。
3臨時(shí)存儲(chǔ)過程
分為兩種存儲(chǔ)過程:一是本地臨時(shí)存儲(chǔ)過程过咬,以“#”開頭,這樣的存儲(chǔ)過程就是存放在tempdb數(shù)據(jù)庫(kù)中的本地臨時(shí)存儲(chǔ)過程制妄,且只有創(chuàng)建它的用戶才能執(zhí)行它; 二是全局臨時(shí)存儲(chǔ)過程掸绞,以“##”開頭,這樣的存儲(chǔ)過程就是存儲(chǔ)在tempdb數(shù)據(jù)庫(kù)中的全局臨時(shí)存儲(chǔ)過程耕捞,全局臨時(shí)存儲(chǔ)過程一旦創(chuàng)建衔掸,以后連接到服務(wù)器的任意用戶都可以執(zhí)行它,而且不需要特定的權(quán)限俺抽。
4遠(yuǎn)程存儲(chǔ)過程
在SQL Server2005中敞映,遠(yuǎn)程存儲(chǔ)過程(Remote Stored Procedures)是位于遠(yuǎn)程服務(wù)器上的存儲(chǔ)過程,通沉赘可以使用分布式查詢和EXECUTE命令執(zhí)行一個(gè)遠(yuǎn)程存儲(chǔ)過程振愿。
5擴(kuò)展存儲(chǔ)過程
擴(kuò)展存儲(chǔ)過程(Extended Stored Procedures)是用戶可以使用外部程序語(yǔ)言編寫的存儲(chǔ)過程,而且擴(kuò)展存儲(chǔ)過程的名稱通常以xp_開頭弛饭。
創(chuàng)建存儲(chǔ)過程的基本代碼結(jié)構(gòu):
create procedure Procedure_Name //Procedure_Name為存儲(chǔ)過程(不能以阿拉伯?dāng)?shù)字開頭)冕末,在一個(gè)數(shù)據(jù)庫(kù)中觸發(fā)器名是唯一的。
@Param1 int ,@Param2 int//@Param1和 @Param2為存儲(chǔ)過程的參數(shù)孩哑,DataType為參數(shù)類型栓霜,多個(gè)參數(shù)采用“,”隔開
AS//存儲(chǔ)過程要執(zhí)行的操作
BEGIN
--begin跟end組成,可以不寫横蜒,如果執(zhí)行sql語(yǔ)句較為麻煩胳蛮,則使用BEGIN END會(huì)使得代碼更加整齊,容易理解
END
GO //操作完成
exec Procedure_Name[采納數(shù)名] //調(diào)用存儲(chǔ)過程
存儲(chǔ)過程優(yōu)缺點(diǎn)總結(jié):
優(yōu)點(diǎn)
1.存儲(chǔ)過程只在創(chuàng)造時(shí)進(jìn)行編譯丛晌,以后每次執(zhí)行存儲(chǔ)過程都不需再重新編譯仅炊,而一般SQL語(yǔ)句每執(zhí)行一次就編譯一次,所以使用存儲(chǔ)過程可提高數(shù)據(jù)庫(kù)執(zhí)行速度。
2.當(dāng)對(duì)數(shù)據(jù)庫(kù)進(jìn)行復(fù)雜操作時(shí)(如對(duì)多個(gè)表進(jìn)行Update,Insert,Query,Delete時(shí))澎蛛,可將此復(fù)雜操作用存儲(chǔ)過程封裝起來與數(shù)據(jù)庫(kù)提供的事務(wù)處理結(jié)合一起使用抚垄。
3.存儲(chǔ)過程可以重復(fù)使用,可減少數(shù)據(jù)庫(kù)開發(fā)人員的工作量(復(fù)用性高,面向?qū)ο蟮木幊趟枷?
4.安全性高,可設(shè)定只有某些用戶才具有對(duì)指定存儲(chǔ)過程的使用權(quán)
缺點(diǎn)
1.調(diào)試麻煩,但是用 PL/SQL Developer 調(diào)試很方便呆馁!彌補(bǔ)這個(gè)缺點(diǎn)桐经。
2.移植問題,數(shù)據(jù)庫(kù)端代碼當(dāng)然是與數(shù)據(jù)庫(kù)相關(guān)的浙滤。但是如果是做工程型項(xiàng)目阴挣,基本不存在移植問題。
3.重新編譯問題纺腊,因?yàn)楹蠖舜a是運(yùn)行前編譯的畔咧,如果帶有引用關(guān)系的對(duì)象發(fā)生改變時(shí),受影響的存儲(chǔ)過程揖膜、包將需要重新編譯(不過也可以設(shè)置成運(yùn)行時(shí)刻自動(dòng)編譯)誓沸。
4.如果在一個(gè)程序系統(tǒng)中大量的使用存儲(chǔ)過程,到程序交付使用的時(shí)候隨著用戶需求的增加會(huì)導(dǎo)致數(shù)據(jù)結(jié)構(gòu)的變化壹粟,接著就是系統(tǒng)的相關(guān)問題了拜隧,最后如果用戶想維護(hù)該系統(tǒng)可以說是很難很難、而且代價(jià)是空前的煮寡,維護(hù)起來更麻煩虹蓄。
簡(jiǎn)單秒殺存儲(chǔ)過程
DELIMITER $$ --console; 轉(zhuǎn)化為$$
--定義存儲(chǔ)過程
--參數(shù):in 輸入?yún)?shù);out 輸出參數(shù)
--row_count();返回上一條修改類型sql(delete犀呼、insert幸撕、update)的影響行數(shù)
--row_count:0 未修改數(shù)據(jù) >0 表示修改的行數(shù);<0:sql錯(cuò)誤/未執(zhí)行系應(yīng)該sql
CREATE PROCEDURE `seckill`.`excute_seckill`
(in v_seckill_id bigint,in v_phone VARCHAR,in v_kill_time TIMESTAMP,out r_result int)
BEGIN
DECLARE insert_count int default 0;
START TRANSACTION;
insert ignore into success_killed
(seckill_id,user_phone,create_time)
values (v_seckill_id,v_phone,v_kill_time)
select row_count() into insert_count;
IF (insert_count<0) THEN
ROLLBACK ;
set r_result = -1;
ELSEIF(insert_count<0) THEN
ROLLBACK ;
SET r_result = -2;
ELSE
update seckil set number = number-1
where seckill_id = v_seckill_id
and end_time > v_kill_time
and start_time < v_kill_time
and number > 0;
select row_count() into insert_count;
IF(insert_count==0) THEN
ROLLBACK ;
SET r_result = 0;
ELSEIF(insert_count < 0) THEN
ROLLBACK ;
SET r_result = -2;
ELSE
COMMIT;
SET r_result = 0;
END IF;
END IF;
END;
$$
--存儲(chǔ)過程定義結(jié)束
DELIMITER ;
set @r_result = -3;
--調(diào)用執(zhí)行存儲(chǔ)過程
call execute_seckill(1003,15400899706,now(),@r_result);
--獲取結(jié)果
select @r_result;