SqlServer存儲過程的創(chuàng)建與使用

目錄


回到頂部

什么是存儲過程屎媳?

T-SQL中的存儲過程,非常類似于net語言中的方法论巍,它可以重復調用烛谊。當存儲過程執(zhí)行一次后,可以將語句緩存中嘉汰,這樣下次執(zhí)行的時候直接使用緩存中的語句丹禀。

這樣就可以提高存儲過程的性能。

  1. 存儲過程Procedure是一組為了完成特定功能的SQL語句集合鞋怀,經編譯后存儲在數據庫中双泪,用戶通過指定存儲過程的名稱并給出參數來執(zhí)行。
  2. 存儲過程中可以包含邏輯控制語句和數據操縱語句密似,它可以接受參數焙矛、輸出參數、返回單個或多個結果集以及返回值残腌。
  3. 由于存儲過程在創(chuàng)建時即在數據庫服務器上進行了編譯并存儲在數據庫中村斟,所以存儲過程運行要比單個的SQL語句塊要快。
  4. 同時由于在調用時只需用提供存儲過程名和必要的參數信息抛猫,所以在一定程度上也可以減少網絡流量蟆盹、簡單網絡負擔。
image
image

回到頂部

存儲過程的優(yōu)點

1邑滨、存儲過程允許標準組件式編程

存儲過程創(chuàng)建后可以在程序中被多次調用執(zhí)行日缨,而不必重新編寫該存儲過程的SQL語句。

而且數據庫專業(yè)人員可以隨時對存儲過程進行修改掖看,但對應用程序源代碼卻毫無影響匣距,從而極大的提高了程序的可移植性。

2哎壳、存儲過程能夠實現較快的執(zhí)行速度

如果某一操作包含大量的T-SQL語句代碼毅待,分別被多次執(zhí)行,那么存儲過程要比批處理的執(zhí)行速度快得多归榕。

因為存儲過程是預編譯的尸红,在首次運行一個存儲過程 時,查詢優(yōu)化器對其進行分析刹泄、優(yōu)化外里,并給出最終被存在系統表中的存儲計劃。

而批處理的T-SQL語句每次運行都需要預編譯和優(yōu)化特石,所以速度就要慢一些盅蝗。

3、存儲過程減輕網絡流量

對于同一個針對數據庫對象的操作姆蘸,如果這一操作所涉及到的T-SQL語句被組織成一存儲過程墩莫,

那么當在客戶機上調用該存儲過程時,網絡中傳遞的只是該調用語句逞敷,否則將會是多條SQL語句狂秦。

從而減輕了網絡流量,降低了網絡負載推捐。

4裂问、存儲過程可被作為一種安全機制來充分利用

系統管理員可以對執(zhí)行的某一個存儲過程進行權限限制,從而能夠實現對某些數據訪問的限制牛柒,避免非授權用戶對數據的訪問愕秫,保證數據的安全。

image

回到頂部

存儲過程的缺點

1焰络、運行速度

對于很簡單的sql戴甩,存儲過程運行速度沒有什么優(yōu)勢。

2闪彼、代碼可讀性差甜孤,不易于維護

存儲過程的開發(fā)調試要比一般程序困難(老版本DB2還只能用C寫存儲過程,更是一個災難)畏腕。

代碼可讀性差缴川,不易于難維護。

3描馅、可移植性差

由于存儲過程將應用程序綁定到SQLServer把夸,因此使用存儲過程封裝業(yè)務邏輯將限制應用程序的可移植性。

如果應用程序的可移植性在您的環(huán)境中非常重要铭污,則將業(yè)務邏輯封裝在不特定于RDBMS的中間層中可能是一個更佳的選擇恋日。


回到頂部

存儲過程的基本語法

變量的聲明:
聲明變量時必須在變量前加@符號
declare @num int

變量的賦值:
變量賦值時變量前必須加set
set @num= 30

聲明多個變量:
declare @name varchar(10),@num int

if語句的使用:

declare @d int
set @d = 1
IF @d = 1
BEGIN
    PRINT '正確' 
END 
ELSE BEGIN 
    PRINT '錯誤' 
END

多條件選擇語句:

declare @today int
declare @week nvarchar(3)
set @today=3
set @week= case
     when @today=1 then '星期一'
     when @today=2 then '星期二'
     when @today=3 then '星期三'
     when @today=4 then '星期四'
     when @today=5 then '星期五'
     when @today=6 then '星期六'
     when @today=7 then '星期日'
     else '值錯誤'
end
print @week

循環(huán)語句:

DECLARE @i INT
SET @i = 1
WHILE @i<1000000 BEGIN
set @i=@i+1
END

定義游標:

DECLARE @cur1 CURSOR FOR SELECT .........

OPEN @cur1
FETCH NEXT FROM @cur1 INTO 變量
WHILE(@@FETCH_STATUS=0)
BEGIN
處理.....
FETCH NEXT FROM @cur1 INTO 變量
END
CLOSE @cur1
DEALLOCATE @cur1

回到頂部

存儲過程的分類

1膀篮、系統存儲過程

系統存儲過程是系統創(chuàng)建的存儲過程,目的在于能夠方便的從系統表中查詢信息或完成與更新數據庫表相關的管理任務或其他的系統管理任務岂膳。

系統存儲過程主要存 儲在master數據庫中誓竿,以“sp”下劃線開頭的存儲過程。

盡管這些系統存儲過程在master數據庫中谈截,但我們在其他數據庫還是可以調用系統存儲過 程筷屡。

有一些系統存儲過程會在創(chuàng)建新的數據庫的時候被自動創(chuàng)建在當前數據庫中。

1.1簸喂、系統存儲過程sql示例

--表重命名
exec sp_rename 'stu', 'stud';--列重命名
exec sp_rename 'stud.name', 'sName', 'column';
exec sp_help 'stud';
--重命名索引
exec sp_rename N'student.idx_cid', N'idx_cidd', N'index';
exec sp_help 'student';

--查詢所有存儲過程
select * from sys.objects where type = 'P';
select * from sys.objects where type_desc like '%pro%' and name like 'sp%';

2毙死、自定義存儲過程

所謂自定義存儲過程,是指為了完成某一段特定的功能需求喻鳄,在用戶數據庫中利用t-sql自行編輯的語句集合扼倘,在用戶自定義的過程中可以有輸入參數,返回的輸出參數及返回至客戶端的信息與結果 诽表。

如果在存儲過程名稱前加了“##”符號唉锌,表示創(chuàng)建的存儲過程是臨時的全局性的;

如果前面的為“#”符號竿奏,表示所創(chuàng)建的存儲過程是臨時的局部的袄简,該存儲過程只能在創(chuàng)建它的會話中使用。

以上兩種存儲過程創(chuàng)建后都存放在tempdb數據庫中泛啸。

用戶自定義存儲過程還可以細分為t-sql語言存儲過程和CLR存儲過程绿语。CLR存儲過程是指利用.NET框架公共語言編輯的存儲過程,既可以接受用戶提供的參數又可以返回存儲過程的運行結果候址,通常用作某個類的公共靜態(tài)方法吕粹。

2.1、創(chuàng)建不帶參數存儲過程

--創(chuàng)建一個返回結果集的存儲過程(proc或者procedure均可)
if (object_id('proc_get_student', 'P') is not null)--判斷存儲過程是否存在 另外一種 if (exists (select * from sys.objects where name = 'proc_get_student'))//
drop proc proc_get_student --刪除存儲過程
go
create proc proc_get_student --創(chuàng)建存儲過程
as
select * from student; --結果集

--調用執(zhí)行存儲過程岗仑,得到返回集(exec或者execute均可)
exec proc_get_student;

2.2匹耕、修改存儲過程

--修改存儲過程
alter proc proc_get_student
as
select * from student;  --修改后的SQL語句

--調用執(zhí)行存儲過程,得到返回集(exec或者execute均可)
exec proc_get_student;

2.3荠雕、帶參數存儲過程

--創(chuàng)建一個返回結果集的存儲過程(proc或者procedure均可)
if (object_id('proc_find_stu', 'P') is not null)--判斷存儲過程是否存在
drop proc proc_find_stu
go
create proc proc_find_stu(@startId int, @endId int)--兩個參數
as
select * from student where id between @startId and @endId   --查詢語句
go

--調用執(zhí)行存儲過程稳其,2,4為參數
exec proc_find_stu 2, 4;

2.4、帶通配符參數存儲過程

--創(chuàng)建一個返回結果集的存儲過程(proc或者procedure均可)
if (object_id('proc_findStudentByName', 'P') is not null)
drop proc proc_findStudentByName
go
create proc proc_findStudentByName(@name varchar(20) = '%j%', @nextName varchar(20) = '%')
as
select * from student where name like @name and name like @nextName;
go

--調用執(zhí)行存儲過程
exec proc_findStudentByName;
exec proc_findStudentByName '%o%', 't%';

2.5炸卑、帶輸出參數存儲過程

--創(chuàng)建一個返回結果集的存儲過程(proc或者procedure均可)
if (object_id('proc_getStudentRecord', 'P') is not null)
drop proc proc_getStudentRecord
go
create proc proc_getStudentRecord(
@id int, --默認輸入參數
@name varchar(20) out, --輸出參數
@age varchar(20) output--輸入輸出參數
)
as
select @name = name, @age = age from student where id = @id and sex = @age;
go

--調用執(zhí)行存儲過程
declare @id int,
@name varchar(20),
@temp varchar(20);
set @id = 7;
set @temp = 1;
exec proc_getStudentRecord @id, @name out, @temp output;
select @name, @temp;
print @name '#' @temp;

3既鞠、擴展存儲過程

通常以“xp_”為前綴標識,在sql server系統外通過執(zhí)行動態(tài)鏈接庫盖文,即DLL文件嘱蛋,來實現的功能,該存儲過程經常使用API接口進行編輯,可以加載到sql server實例的地址空間里試試運行洒敏。

在sql server常見的擴展存儲過程有:

  • xp_enumgroups 指定WINDOWS本地組列表在WINDOWS域中定義的全局組表
  • xp_findnextmsg 接受輸入的郵件ID號龄恋,返回輸出的郵件ID號
  • xp_grantlogin 給用戶分配對sql server2012系統的權限
  • xp_logevent 把用戶自定義消息輸入到sql server日志文件或WINDOWS系統事件查看器中
  • xp_loginconfig 顯示sql server 2012實例運行時登陸的安全配置
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市桐玻,隨后出現的幾起案子篙挽,更是在濱河造成了極大的恐慌荆萤,老刑警劉巖镊靴,帶你破解...
    沈念sama閱讀 217,406評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現場離奇詭異链韭,居然都是意外死亡偏竟,警方通過查閱死者的電腦和手機,發(fā)現死者居然都...
    沈念sama閱讀 92,732評論 3 393
  • 文/潘曉璐 我一進店門敞峭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來踊谋,“玉大人,你說我怎么就攤上這事旋讹≈巢希” “怎么了?”我有些...
    開封第一講書人閱讀 163,711評論 0 353
  • 文/不壞的土叔 我叫張陵沉迹,是天一觀的道長睦疫。 經常有香客問我,道長鞭呕,這世上最難降的妖魔是什么蛤育? 我笑而不...
    開封第一講書人閱讀 58,380評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮葫松,結果婚禮上瓦糕,老公的妹妹穿的比我還像新娘。我一直安慰自己腋么,他們只是感情好咕娄,可當我...
    茶點故事閱讀 67,432評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著珊擂,像睡著了一般圣勒。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上未玻,一...
    開封第一講書人閱讀 51,301評論 1 301
  • 那天灾而,我揣著相機與錄音,去河邊找鬼扳剿。 笑死旁趟,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播锡搜,決...
    沈念sama閱讀 40,145評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼橙困,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了耕餐?” 一聲冷哼從身側響起凡傅,我...
    開封第一講書人閱讀 39,008評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎肠缔,沒想到半個月后夏跷,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 45,443評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡明未,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,649評論 3 334
  • 正文 我和宋清朗相戀三年槽华,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片趟妥。...
    茶點故事閱讀 39,795評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡猫态,死狀恐怖,靈堂內的尸體忽然破棺而出披摄,到底是詐尸還是另有隱情亲雪,我是刑警寧澤,帶...
    沈念sama閱讀 35,501評論 5 345
  • 正文 年R本政府宣布疚膊,位于F島的核電站义辕,受9級特大地震影響,放射性物質發(fā)生泄漏酿联。R本人自食惡果不足惜终息,卻給世界環(huán)境...
    茶點故事閱讀 41,119評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望贞让。 院中可真熱鬧周崭,春花似錦、人聲如沸喳张。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽销部。三九已至摸航,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間舅桩,已是汗流浹背酱虎。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留擂涛,地道東北人读串。 一個月前我還...
    沈念sama閱讀 47,899評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親恢暖。 傳聞我的和親對象是個殘疾皇子排监,可洞房花燭夜當晚...
    茶點故事閱讀 44,724評論 2 354

推薦閱讀更多精彩內容