SqlServer存儲過程詳解

SqlServer存儲過程詳解

1.建立存儲過程的基本語法模板:sql

if (exists (select * from sys.objects where name = 'pro_name'))
    drop proc pro_name
go
create proc pro_name
    @param_name param_type [=default_value]
as
begin    
    sql語句
end

ps:[]表示非必寫內容。sys.objects存儲的是本數據庫中的信息,不單單存儲表名,還有存儲過程名 、視圖名、觸發器等等。數據庫

例如:編程

 1 if (exists (select * from sys.objects where name = 'USP_GetAllUser'))
 2     drop proc USP_GetAllUser
 3 go
 4 create proc USP_GetAllUser
 5 @UserId int =1
 6 as 
 7 set nocount on;
 8 begin
 9     select * from UserInfo where Id=@UserId
10 end

ps:SQL Server 實用工具將 GO 解釋爲應將當前的 Transact-SQL 批處理語句發送給 SQL Server 的信號。當前批處理語句是自上一 GO 命令後輸入的全部語句,如果第一條 GO 命令,則是從特殊會話或腳本的開始處到這條 GO 命令之間的全部語句。緩存

2.調用方法:架構

exec dbo.USP_GetAllUser 2;

 

ps:通常在執行存儲過程是,最好加上架構名稱,例如  dbo.USP_GetAllUser  這樣能夠能夠減小沒必要要的系統開銷,提升性能。 由於若是在存儲過程名稱前面沒有加上架構名稱,SQL SERVER 首先會從當前數據庫sys schema(系統架構)開始查找,若是沒有找到,則會去其它schema查找,最後在dbo架構(系統管理員架構)裏面查找。工具

 

3.查看本數據庫中存在的存儲過程性能

依次展開數據庫、可編程性、存儲過程,便可看到已建立的存儲過程。優化

4.修改存儲過程spa

alter proc proc_name
as
  sql語句

5.存儲過程當中的輸出參數的使用code

 1 if (exists(select * from  sys.objects where name='GetUser'))
 2     drop proc GetUser
 3 go 
 4 create proc GetUser
 5     @id int output,
 6     @name varchar(20) out
 7 as 
 8 begin 
 9     select @id=Id,@name=Name from UserInfo where Id=@id
10 end
11 
12 go 
13 declare 
14 @name varchar(20),
15 @id int;
16 set @id=3;
17 exec dbo.GetUser @id,@name out;
18 select @id,@name;
19 print Cast(@id as varchar(10))+'-'+@name;

ps:參數output爲該參數能夠輸出

6.分頁獲取數據的存儲過程

 1 if (exists(select * from  sys.objects where name='GetUserByPage'))
 2     drop proc GetUserByPage
 3 go 
 4 create proc GetUserByPage
 5     @pageIndex int,
 6     @pageSize int
 7 as 
 8 declare 
 9 @startIndex int,
10 @endIndex int;
11 set @startIndex =  (@pageIndex-1)*@pageSize+1;
12 set @endIndex = @startIndex + @pageSize -1 ;
13 begin 
14     select Id,Name from 
15     (
16         select *,row_number()over (order by Id)as number from UserInfo  
17     )t where t.number>=@startIndex and t.number<=@endIndex
18 end
19 
20 go 
21 exec dbo.GetUserByPage 2,4;

7.存儲過程當中事務的建立

if (exists(select * from  sys.objects where name='JayJayToTest'))
    drop proc JayJayToTest
go 
create proc JayJayToTest
    @GiveMoney int,
    @UserName nvarchar(20)
as 
beginset nocount on;
    begin tran;
    begin try
        update BankTest set Money = Money-@GiveMoney where Name=@UserName;
        update BankTest set Money = Money+@GiveMoney where Name='test';
        commit;
    end try    
    begin catch        
        rollback tran;
        print ('發生異常,事務進行回滾');
    end catch    
end
go
exec JayJayToTest 10,'jayjay'

8.瞭解存儲過程的執行計劃

SELECT * FROM sys.[syscacheobjects]查看當前緩存的執行計劃

若是執行存儲過程時成功經過解析階段,則 Microsoft SQL Server 查詢優化器將分析存儲過程當中的 Transact-SQL 語句並建立一個執行計劃。執行計劃描述執行存儲過程的最快方法,所依據的信息包括:

  1.表中的數據量。

  2.表的索引的存在及特徵,以及數據在索引列中的分佈。

  3.WHERE 子句條件所使用的比較運算符和比較值。

  4.是否存在聯接以及 UNION、GROUP BY 和 ORDER BY 關鍵字。

查詢優化器在分析完存儲過程當中的這些因素後,將執行計劃置於內存中。分析存儲過程和建立執行計劃的過程稱爲編譯。優化的內存中的執行計劃將用來執行該查詢。執行計劃將駐留在內存中,直到從新啓動 SQL Server 或其餘對象須要存儲空間時爲止。若是隨後執行了存儲過程,而現有執行計劃仍留在內存中,則 SQL Server 將重用現有執行計劃。若是執行計劃再也不位於內存中,則建立新的執行計劃。

從新編譯執行計劃(create proc JayJayToTest with recompile)

建立存儲過程時在其定義中指定 WITH RECOMPILE 選項,代表 SQL Server 將不對該存儲過程計劃進行高速緩存;該存儲過程將在每次執行時都從新編譯。當存儲過程的參數值在各次執行間都有較大差別,致使每次均需建立不一樣的執行計劃時,可以使用 WITH RECOMPILE 選項。此選項並不經常使用,由於每次執行存儲過程時都必須對其進行從新編譯,這樣會使存儲過程的執行變慢。

因爲數據庫的新狀態,數據庫內的某些更改可能會致使執行計劃效率低下或再也不有效。SQL Server 檢測這些使執行計劃無效的更改,並將計劃標記爲無效。此後,必須爲執行查詢的下一個鏈接從新編譯新的計劃。致使計劃無效的狀況包括:

  1.對查詢所引用的表或視圖進行任何結構更改(ALTER TABLE 和 ALTER VIEW)。
  2.經過語句(如 UPDATE STATISTICS)顯式生成或者自動生成新的分發內容統計。
  3.除去執行計劃所使用的索引。
  4.顯式調用 sp_recompile。
  5.對鍵的大量更改(其餘用戶對由查詢引用的表使用 INSERT 或 DELETE 語句所產生的修改)。
  6.對於帶觸發器的表,inserted 或 deleted 表內的行數顯著增加。

相關文章
相關標籤/搜索