?MS SQL Server目前正日益成為WindowNT操作系統(tǒng)上面最為重要的一種數據庫管理系統(tǒng),隨著MSSQLServer2000的推出,微軟的這種數據庫服務系統(tǒng)真正的實現了在WindowsNT/2000系列操作系統(tǒng)一統(tǒng)天下的局面,在微軟的操作系統(tǒng)上面,沒有任何一種數據庫系統(tǒng)能與之相抗衡,包括數據庫領域的領頭羊甲骨文公司的看家數據庫系統(tǒng)Oracle在內
不可否認,MSSQLServer最大的缺陷就是只能運行在微軟自己的操作系統(tǒng)上面,這一點是MSSQLServer的致命傷口
但在另一方面卻也成了最好的促進劑,促使MSSQLServer在自己僅有的“土地”上面將自己的功能發(fā)揮到了極至,最大限度的利用了WindowsNT系列操作系統(tǒng)的各種潛能!作為MSSQLServer數據庫系統(tǒng)中很重要的一個概念就是存儲過程,合理的使用存儲過程,可以有效的提高程序的性能;并且將商業(yè)邏輯封裝在數據庫系統(tǒng)中的存儲過程中,可以大大提高整個軟件系統(tǒng)的可維護性,當你的商業(yè)邏輯發(fā)生了改變的時候,不再需要修改并編譯客戶端應用程序以及重新分發(fā)他們到為數眾多的用戶手中,你只需要修改位于服務器端的實現相應商業(yè)邏輯的存儲過程即可
合理的編寫自己需要的存儲過程,可以最大限度的利用MSSQLServer的各種資源
下面我們來共同看看各種編寫MSSQLServer存儲過程和使用存儲過程的技巧經驗!下面我們討論的前提都是您有過一定的MSSQLServer存儲過程的編寫經驗,下面的各種技巧如果沒有特別注明,則同時適用于MSSQLServer7.0和MSSQLServer2000
1、使用OUTPUT類型參數的存儲過程的技巧一般的存儲過程都是直接返回一段記錄集給調用者,但是有的時候我們只需要一些存儲過程返回的一些參數的值,這時候可以指定存儲過程的OUTPUT參數,比如
CreateprocedureGetName@uidnvarchar(1),@usernamnvarchar(10)=''outputASset@username='hongchao'GO在上面的存儲過程當中我們傳遞進的參數是@uid,而參數@username則在調有的時候不需要傳遞進去
這樣,存儲過程會返回給我們參數@username的值是‘hongchao’
上面的都比較的容易,需要注意的是,當在SQL2000中的時候,如果你的存儲過程只有一個參數,并且這個參數是OUTPUT類型的,你必須在調用這個存儲過程的時候給這個參數一個初始的值,否則會出現調用錯誤的情況!2、在存儲過程中的書寫注意事項這一點在MSSQLServer7.0和MSSQLServer2000種有些地方是不一樣的,也不知道是不是微軟的遺漏,那就是有些系統(tǒng)的關鍵字在不同的版本之間有所不同,比如關鍵字level,同樣的一句話
select*fromuserswherelevel=1在MSSQLServer7當中的存儲過程當中運行沒有絲毫的問題,但是到了MSSQLServer2000當中則會出現運行的錯誤,原因就是在于在MSSQLServer2000中“l(fā)evel”被當作了關鍵字(奇怪的是SQL7當中也同樣是關鍵字,卻沒問題),所以在SQL2000當中,上面的語句應當改為:select*fromuserswhere[level]=1從上面的例子中我們可以看到,在你編寫存儲過程的時候,最好在有可能和系統(tǒng)關鍵字的地方使用“[”和“]”將他包圍起來,以避免在移植過程中出現的運行錯誤問題
3、在存儲過程中使用系統(tǒng)存儲過程SP_Executesql的注意事項我們在編寫自己的存儲過程的時候,往往在很多的情況下,會使用到系統(tǒng)的存儲過程SP_Execute
但是需要的注意的是,如果你在這個存儲過程的參數(一般是一段SQL語句)當中進行了臨時Table的操作,那末對于調用者來說,這個臨時Table是不可見的,也就是說你無法通過臨時Table來在調用者和被調用者之間傳遞值
解決的方法是使用全局臨時Table,也就是“##”開頭的Table
4、在存儲過程中使用臨時Table和游標的注意事項如果我們的商業(yè)邏輯比較復雜,在存儲過程當中,就需要一些媒介作為中轉臺,這時候臨時表舅發(fā)揮了作用,但是請務必記得在使用完之后,即使刪除使用到的臨時Table
而在存儲過程當中想要依次遍歷一個記錄集的唯一方法就是使用系統(tǒng)游標,同樣要注意的是,在使用完成之后及時關閉和銷毀游標對象釋放他用到的資源
并且不在萬不得已的情況下,不要隨意使用游標,因為他會占用較多的系統(tǒng)資源,尤其是對于大并發(fā)量的情況下,很容易使得系統(tǒng)資源耗盡而崩潰
使用臨時Table和游標各有利弊,在使用的過程中要適當的利用即可!5、在存儲過程中調用外部的ActiveXDLL程序有些特殊的情況下,我們可能會需要調用外部的ActiveXDLL程序,這個時候就需要使用到系統(tǒng)的存儲過程sp_OACreate以及其他的相關系統(tǒng)存儲過程,都是以sp_OA開頭的存儲過程,可以自由的在自己的存儲過程當中調用ActiveXDLL的各種方法和屬性
比如下面的例子
DECLARE@objectintDECLARE@hrintDECLARE@propertyvarchar(255)DECLARE@returnvarchar(255)DECLARE@srcvarchar(255),@descvarchar(255)--建立一個對象(SQLDMO.SQLServer).EXEC@hr=sp_OACreate'SQLDMO.SQLServer',@object OUTIF@hr<>0BEGINEXECsp_OAGetErrorInfo@object,@srcOUT,@descOUTSELECThr=convert(varbinary(4),@hr),Source=@src,DeScription=@descRETURNEND--設置對象的屬性.EXEC@hr=sp_OASetProperty@object,'HostName','Gizmo'IF@hr<>0BEGINEXECsp_OAGetErrorInfo@object,@srcOUT,@descOUTSELECThr=convert(varbinary(4),@hr),Source=@src,DESCRIPTION=@descRETURNEND--通過OUTPUT參數獲取對象的屬性值.EXEC@hr=sp_OAGetProperty@object,'HostName',@propertyOUTIF@hr<>0BEGINEXECsp_OAGetErrorInfo@object,@srcOUT,@descOUTSELECThr=convert(varbinary(4),@hr),Source=@src,Description=@descRETURNENDPRINT@property--調用對象的方法EXEC@hr=sp_OAMethod@object,'Connect',NULL,'my_server','my_login','my_password'IF@hr<>0BEGINEXECsp_OAGetErrorInfo@object,@srcOUT,@descOUTSELECThr=convert(varbinary(4),@hr),Source=@src,Description=@descRETURNEND--銷毀已經創(chuàng)建的ActiveX對象EXEC@hr=sp_OADestroy@objectIF@hr<>0BEGINEXECsp_OAGetErrorInfo@object,@srcOUT,@descOUTSELECThr=convert(varbinary(4),@hr),Source=@src,Description=@descRETURNEND6、在存儲過程中使用數據庫事務處理在很多的情況下,我們在存儲過程中都會遇到需要同時操作多個表的情況,這時候就需要避免在操作的過程中由于以外而造成的數據的不一致性
這時候就需要將操作多個表的操作放入到事務中進行處理
但是需要注意的是,不能在事務中使用return語句強行退出,這樣會引發(fā)事務的非正常錯誤,不能保證數據的一致性
并且,一旦將多個處理放入事務當中,系統(tǒng)的處理速度會有所降低,所以應當將頻繁操作的多個可分割的處理過程放入到多個存儲過程當中,這樣會大大提高系統(tǒng)的響應速度,但是前提是不違背數據的一致性
看完了上面的這些編寫SQL Server存儲過程當中的技巧,相信對您或多或少會有些幫助,也希望通過上面的一些經驗總結,可以使得您在應用SQL Server存儲過程的時候,有意識的可以避免一些彎路
(以上所有程序在Windows Advance Server2000中文版+MS SQL Server7.0/2000中文版測試通過)作者
蘇紅超來源:月光博客
請立即點擊咨詢我們或撥打咨詢熱線: 18942620423,我們會詳細為你一一解答你心中的疑難。項目經理在線