SQL Server中的存儲過程是使用T_SQL編寫的代碼段。它的目的在於可以方便的從系統表中查詢信息,或者完成與更新數據庫表相關的管理任務和其餘的系統管理任務.T_SQL語句是SQL Server數據庫與應用程序之間的編程接口。在不少狀況下,一些代碼會被開發者重複編寫屢次,若是每次都編寫相同功能的代碼,不但繁瑣,並且容易出錯,並且因爲SQL Server逐條的執行語句會下降系統的運行效率。java
簡而言之,存儲過程就是SQL Server爲了實現特定任務,而將一些須要屢次調用的固定操做語句,或者某些業務過於繁瑣,須要編寫大量邏輯和查詢,嚴重影響程序性能,編寫成程序段,這些程序段存儲在服務器上,有數據庫服務器經過程序來調用。sql
1.系統存儲過程數據庫
系統存儲過程是 SQL Server系統自身提供的存儲過程,能夠做爲命令執行各類操做。編程
系統存儲過程主要用來從系統表中獲取信息,使用系統存儲過程完成數據庫服務器的管理工做,爲系統管理員提供幫助,爲用戶查看數據庫對象提供方便,系統存儲過程位於數據庫服務器中,而且以sp_開頭,系統存儲過程定義在系統定義和用戶定義的數據庫中,在調用時沒必要在存儲過程前加數據庫限定名。例如:sp_rename系統存儲過程能夠修改當前數據庫中用戶建立對象的名稱,sp_helptext存儲過程能夠顯示規則,默認值或視圖的文本信息,SQL SERVER服務器中許多的管理工做都是經過執行系統存儲過程來完成的,許多系統信息也能夠經過執行系統存儲過程來得到。緩存
系統存儲過程建立並存放在與系統數據庫master中,一些系統存儲過程只能由系統管理員使用,而有些系統存儲過程經過受權能夠被其它用戶所使用。安全
2.用戶存儲過程(自定義存儲過程)服務器
自定義存儲過程即用戶使用T_SQL語句編寫的、爲了實現某一特定業務需求,在用戶數據庫中編寫的T_SQL語句集合,自定義存儲過程能夠接受輸入參數、向客戶端返回結果和信息,返回輸出參數等。建立自定義存儲過程時,存儲過程名前加上"##"表示建立了一個全局的臨時存儲過程;存儲過程前面加上"#"時,表示建立的局部臨時存儲過程。局部臨時存儲過程只能在建立它的回話中使用,會話結束時,將被刪除。這兩種存儲過程都存儲在tempdb數據庫中。網絡
用戶定義的存儲過程分爲兩類:T_SQL 和CLR模塊化
T_SQL:存儲過程是值保存的T_SQL語句集合,能夠接受和返回用戶提供的參數,存儲過程也可能從數據庫向客戶端應用程序返回數據。性能
CLR存儲過程是指引用Microsoft.NET Framework公共語言的方法存儲過程,能夠接受和返回用戶提供的參數,它們在.NET Framework程序集是做爲類的公共靜態方法實現的。
3.擴展存儲過程
擴展存儲過程是以在SQL SERVER環境外執行的動態鏈接(DLL文件)來實現的,能夠加載到SQL SERVER實例運行的地址空間中執行,擴展存儲過程能夠用SQL SERVER擴展存儲過程API編程,擴展存儲過程之前綴"xp_"來標識,對於用戶來講,擴展存儲過程和普通話存儲過程同樣,能夠用相同的方法來執行。
1. 建立無參存儲過程
--1.建立無參存儲過程 if (exists (select * from sys.objects where name = 'getAllBooks')) drop proc proc_get_student go create procedure getAllBooks as select * from books; --調用,執行存儲過程 exec getAllBooks;
2. 修改存儲過程
alter procedure dbo.getAllBooks as select book_auth from books;
3. 刪除存儲過程
drop procedure getAllBooks;
4. 重命名存儲過程
sp_rename getAllBooks,proc_get_allBooks;
5. 建立帶參數的存儲過程,這也是存儲過程最多見的形式
存儲過程的參數分爲兩種:輸入參數和輸出參數
輸入參數:用於向存儲過程傳入值,相似java語言或則c中的值傳遞。
輸出參數:用於調用存儲過程後,參會結果,相似java語言的按引用傳遞。
值傳遞和引用傳遞區別:
5.1)帶一個參數存儲過程
if (exists (select * from sys.objects where name = 'searchBooks')) drop proc searchBooks go create proc searchBooks(@bookID int) as --要求book_id列與輸入參數相等 select * from books where book_id=@bookID; --執行searchBooks exec searchBooks 1;
5.2)帶2個參數存儲過程
if (exists (select * from sys.objects where name = 'searchBooks1')) drop proc searchBooks1 go create proc searchBooks1( @bookID int, @bookAuth varchar(20) ) as --要求book_id和book_Auth列與輸入參數相等 select * from books where book_id=@bookID and book_auth=@bookAuth; exec searchBooks1 1,'金庸';
5.3)建立有返回值的存儲過程
if (exists (select * from sys.objects where name = 'getBookId')) drop proc getBookId go create proc getBookId( @bookAuth varchar(20),--輸入參數,無默認值 @bookId int output --輸入/輸出參數 無默認值 ) as select @bookId=book_id from books where book_auth=@bookAuth --執行getBookId這個帶返回值的存儲過程 declare @id int --聲明一個變量用來接收執行存儲過程後的返回值 exec getBookId '孔子',@id output select @id as bookId;--as是給返回的列值起一個名字
5.4)建立帶通配符的存儲過程
if (exists (select * from sys.objects where name = 'charBooks')) drop proc charBooks go create proc charBooks( @bookAuth varchar(20)='金%', @bookName varchar(20)='%' ) as select * from books where book_auth like @bookAuth and book_name like @bookName; --執行存儲過程charBooks exec charBooks '孔%','論%';
5.5)加密存儲過程
with encryption子句對用戶隱藏存儲過程的文本.下例建立加密過程,使用 sp_helptext 系統存儲過程獲取關於加密過程的信息,而後嘗試直接從 syscomments 表中獲取關於該過程的信息。
if (object_id('books_encryption', 'P') is not null) drop proc books_encryption go create proc books_encryption with encryption as select * from books; --執行此過程books_encryption exec books_encryption; exec sp_helptext 'books_encryption';--控制檯會顯示"對象 'books_encryption' 的文本已加密。"
5.6)不緩存存儲過程
--with recompile不緩存 if (object_id('book_temp', 'P') is not null) drop proc book_temp go create proc book_temp with recompile as select * from books; go exec book_temp; exec sp_helptext 'book_temp';
5.7)建立帶遊標參數的存儲過程
if (object_id('book_cursor', 'P') is not null) drop proc book_cursor go create proc book_cursor @bookCursor cursor varying output as set @bookCursor=cursor forward_only static for select book_id,book_name,book_auth from books open @bookCursor; go --調用book_cursor存儲過程 declare @cur cursor, @bookID int, @bookName varchar(20), @bookAuth varchar(20); exec book_cursor @bookCursor=@cur output; fetch next from @cur into @bookID,@bookName,@bookAuth; while(@@FETCH_STATUS=0) begin fetch next from @cur into @bookID,@bookName,@bookAuth; print 'bookID:'+convert(varchar,@bookID)+' , bookName: '+ @bookName +' ,bookAuth: '+@bookAuth; end close @cur --關閉遊標 DEALLOCATE @cur; --釋放遊標
5.8)建立分頁存儲過程
if (object_id('book_page', 'P') is not null) drop proc book_page go create proc book_page( @TableName varchar(50), --表名 @ReFieldsStr varchar(200) = '*', --字段名(所有字段爲*) @OrderString varchar(200), --排序字段(必須!支持多字段不用加order by) @WhereString varchar(500) =N'', --條件語句(不用加where) @PageSize int, --每頁多少條記錄 @PageIndex int = 1 , --指定當前爲第幾頁 @TotalRecord int output --返回總記錄數 ) as begin --處理開始點和結束點 Declare @StartRecord int; Declare @EndRecord int; Declare @TotalCountSql nvarchar(500); Declare @SqlString nvarchar(2000); set @StartRecord = (@PageIndex-1)*@PageSize + 1 set @EndRecord = @StartRecord + @PageSize - 1 SET @TotalCountSql= N'select @TotalRecord = count(*) from ' + @TableName;--總記錄數語句 SET @SqlString = N'(select row_number() over (order by '+ @OrderString +') as rowId,'+@ReFieldsStr+' from '+ @TableName;--查詢語句 -- IF (@WhereString! = '' or @WhereString!=null) BEGIN SET @TotalCountSql=@TotalCountSql + ' where '+ @WhereString; SET @SqlString =@SqlString+ ' where '+ @WhereString; END --第一次執行獲得 --IF(@TotalRecord is null) -- BEGIN EXEC sp_executesql @totalCountSql,N'@TotalRecord int out',@TotalRecord output;--返回總記錄數 -- END ----執行主語句 set @SqlString ='select * from ' + @SqlString + ') as t where rowId between ' + ltrim(str(@StartRecord)) + ' and ' + ltrim(str(@EndRecord)); Exec(@SqlString) END --調用分頁存儲過程book_page exec book_page 'books','*','book_id','',3,1,0; -- declare @totalCount int exec book_page 'books','*','book_id','',3,1,@totalCount output; select @totalCount as totalCount;--總記錄數。