MS SQL高階——檢視與儲存過程
阿新 • • 發佈:2022-05-29
檢視與儲存過程
什麼是檢視
檢視的概念
- 是儲存在伺服器端的一個查詢塊,是一張虛擬表。
- 表示一張表的部分資料或多張表的綜合資料。
- 其結構和資料是建立在對錶的查詢基礎上。
- 檢視的使用,跟對普通的表的查詢使用完全一樣。
檢視中不存放資料
- 資料存放在檢視所引用的原始表中。
表檢視的多樣性
- 一個或多個原始表,根據不同使用者的不同需求,可以建立不同的檢視。
檢視的用途
- 篩選表中的行。
- 防止未經許可的使用者訪問敏感資料。
- 降低資料庫的複雜程度。
- 將多個物理資料庫抽象為一個邏輯資料庫。
如何建立檢視
使用管理器建立檢視
T-SQL語句管理檢視
使用T-SQL語句建立檢視
CREATE VIEWview_Stulnfo AS <SELECT語句>
1 use StudentManager 2 go 3 --判斷檢視是否存在 4 if exists(select * from sysobjects where name='view_ScoreQuery') 5 drop view view_ScoreQuery 6 go 7 --建立檢視 8 create view view_ScoreQuery 9 as 10 select top 1000 Students.StudentId,StudentName,ClassName,View Code11 C#=CSharp,SQLDB=SQLServerDB, 12 ScoreSum=(CSharp+SQLServerDB) from Students 13 inner join ScoreList on Students.StudentId=ScoreList.StudentId 14 inner join StudentClass on Students.ClassId=StudentClass.ClassId 15 order by StudentClass.ClassId16 go 17 --使用檢視查詢 18 select * from view_ScoreQuery
使用T-SQL語句刪除檢視
IF EXISTS (SELECT*FROM sysobjects WHERE name = view_Stulnfo) DROP VIEW view_Stulnfo
使用T-SQL語句檢視檢視
SELECT* FROM view Stulnfo
建立成績查詢檢視
使用檢視注意事項
- 檢視中可以使用多個表
- 一個檢視可以巢狀另一個檢視(儘量少套用)
- 檢視定義中的SELECT語句不能包括下列內容:
- ORDER BY子句,除非在SELECT語句的選擇列表中也有一個 TOP子句。
- INTO關鍵字。
- 引用臨時表或表變數。
什麼是儲存過程
概念
- 預先儲存好的SQL程式
- 儲存在SQLServer中(跟檢視的儲存方式一樣)
- 通過名稱和引數執行
- 在資料庫伺服器端直接呼叫(DBA)
- 供應用程式呼叫(軟體開發工程師)
類似於Java和C#語言中的方法
- 可帶引數,也可返回結果
- 可包含資料操縱語句、變數、邏輯控制語句等
儲存過程的優點
- 執行速度更快
- 允許模組化程式設計
- 提高系統安全性
- 減少網路流通量
- 檢視和儲存過程的重要優點:安全且執行速度快
應用程式傳送SQL的過程
<傳輸語句> <語法檢查> < 語句優化> <語句編譯> <語句執行>
應用程式呼叫儲存過程或檢視的過程
<傳輸引數> <語句執行>
儲存過程的分類
系統儲存過程
- 系統儲存過程的名稱一般以“sp_”開頭。
- 由SQLServer建立、管理和使用。
- 存放在Master資料庫中。
- 目類似Java和C#語言類庫中的方法。
擴充套件儲存過程
- 擴充套件儲存過程的名稱通常以“xp_”開頭。
- 使用程式語言(如C#)建立的外部儲存過程。
- 以DLL形式單獨存在。
使用者自定義儲存過程
- 由使用者在自己的資料庫中建立的儲存過程。
- 類似C#語言中使用者自定義的方法。
呼叫儲存過程
呼叫儲存討程的語法
EXECUTE 過程名[引數]
EXEC 過程名[引數]
如果執行儲存過程的語句是批處理中的第一個語句,則可以不指定EXECUTE關鍵字
常用的系統儲存過程
常用系統儲存過程呼叫示例
1 sp_databases 2 3 EXEC sp_renamedb 'ProductDB','pDB' 4 5 USE StudentManager 6 GO 7 sp_tables 8 9 EXEC sp_columns Students 10 11 EXEC sp_help Students 12 13 EXEC sp_helpconstraint Students 14 15 EXEC sp_stored_proceduresView Code
常用的系統儲存過程
系統儲存過程 | 說明 |
sp_databases | 列出伺服器上的所有資料庫 |
sp_helpdb | 報告有關指定資料庫或所有資料庫的資訊 |
sp_renamedb | 更改資料庫的名稱 |
sp_tables | 返回當前環境下可查詢的物件的列表 |
sp_columns | 返回某個表列的資訊 |
sp_help | 檢視某個表的所有資訊 |
sp_helpconstraint | 檢視某個表的約束 |
sp_helpindex | 檢視某個表的索引 |
sp_stored_procedures | 列出當前環境中的所有儲存過程 |
sp_password | 新增或修改登入帳戶的密碼 |
sp_helptext | 顯示預設值、未加密的儲存過程、使用者定義的儲存過程、觸發器或檢視的實際文字 |
常用擴充套件儲存過程
xp_cmdshell
- 可以執行DOS命令下的一些的操作。
- 以文字行方式返回任何輸出。
1 USE master 2 GO 3 EXEC xp_cmdshell 'mkdir D:\ProductDB', NO_OUTPUT 4 IF EXISTS(SELECT * FROM sysdatabases WHERE name='ProductDB') 5 DROP DATABASE ProductDB 6 GO 7 --CREATE DATABASE ProductDB 8 -- ( 9 -- … 10 --) 11 --GO 12 EXEC xp_cmdshell 'dir D:\ProductDB\' -- 檢視檔案View Code
如何建立儲存過程
定義儲存過程的語法
儲存過程的引數
- 和C#語言的方法一樣,引數可選。
- 引數分為輸入引數、輸出引數。
- 輸入引數允許有預設值。
建立、執行無參的儲存過程
建立儲存過程usp_ScoreQuery
- 查詢考試成績,顯示:學號、姓名、班級、總成績,並按成績的總分高低排序。
- 統計分析考試成績,顯示班級名稱、C#平均分、資料庫平均分,按照班級分組實現。
程式碼編寫分析
1 use StudentManager 2 go 3 if exists(select * from sysobjects where name='usp_ScoreQuery') 4 drop procedure usp_ScoreQuery 5 go 6 create procedure usp_ScoreQuery --建立儲存過程 7 as 8 --查詢考試資訊 9 select Students.StudentId,StudentName,ClassName, 10 ScoreSum=(CSharp+SQLServerDB) from Students 11 inner join StudentClass on StudentClass.ClassId=Students.ClassId 12 inner join ScoreList on Students.StudentId=ScoreList.StudentId 13 order by ScoreSum DESC 14 --統計分析考試資訊 15 select StudentClass.ClassId,C#Avg=avg(CSharp),DBAvg=avg(SQLServerDB) into #scoreTemp 16 from StudentClass 17 inner join Students on StudentClass.ClassId=Students.ClassId 18 inner join ScoreList on ScoreList.StudentId=Students.StudentId 19 group by StudentClass.ClassId order by ClassId 20 select ClassName,C#Avg,DBAvg from #scoreTemp 21 inner join StudentClass on StudentClass.ClassId=#scoreTemp.ClassId 22 go 23 exec usp_ScoreQuery --呼叫儲存過程View Code
儲存過程引數
儲存過程的引數分兩種:
- 輸入引數:向儲存過程傳入值
- 輸出引數:呼叫儲存過程後,傳出執行結果
帶輸入引數的儲存過程
查詢考試成績,要求能夠按照自定義的及格線查詢結果?
1 use StudentManager 2 go 3 if exists(select * from sysobjects where name='usp_ScoreQuery2') 4 drop procedure usp_ScoreQuery2 5 go 6 --建立帶引數的儲存過程 7 create procedure usp_ScoreQuery2 8 @CSharp int, 9 @DB int 10 as 11 select Students.StudentId,StudentName,C#=CSharp,DB=SQLServerDB 12 from Students 13 inner join ScoreList on Students.StudentId=ScoreList.StudentId 14 where CSharp<@CSharp or SQLServerDB<@DB 15 go 16 --呼叫帶引數的儲存過程 17 exec usp_ScoreQuery2 60,65 --按照引數順序賦值 18 exec usp_ScoreQuery2 @DB=65,@CSharp=60 --引數順序可以調換View Code
輸入引數的預設值
查詢中,如果使用者沒有輸入及格線引數,則預設60
1 use StudentManager 2 go 3 if exists(select * from sysobjects where name='usp_ScoreQuery3') 4 drop procedure usp_ScoreQuery3 5 go 6 --建立帶引數的儲存過程 7 create procedure usp_ScoreQuery3 8 @CSharp int=60, 9 @DB int=60 10 as 11 select Students.StudentId,StudentName,C#=CSharp,DB=SQLServerDB 12 from Students 13 inner join ScoreList on Students.StudentId=ScoreList.StudentId 14 where CSharp<@CSharp or SQLServerDB<@DB 15 go 16 --呼叫帶引數的儲存過程 17 exec usp_ScoreQuery3 65 --第二個引數沒有賦值,則預設 18 exec usp_ScoreQuery3 @DB=65 19 exec usp_ScoreQuery3 default,65 --不使用顯示方式賦值 20 exec usp_ScoreQuery3 --兩個引數都是用預設引數View Code
建立帶輸出引數的儲存過程
問題:查詢考試成績,要求自定義分數線,顯示查詢列表,並輸出缺考總人數、不及格總人數?
1 use StudentManager 2 go 3 if exists(select * from sysobjects where name='usp_ScoreQuery4') 4 drop procedure usp_ScoreQuery4 5 go 6 create procedure usp_ScoreQuery4 --建立帶引數的儲存過程 7 @AbsentCount int output,--缺考總人數 8 @FailedCount int output,--不及格總人數 9 @CSharp int=60, 10 @DB int=60 11 as 12 select Students.StudentId,StudentName,C#=CSharp,DB=SQLServerDB 13 from Students 14 inner join ScoreList on Students.StudentId=ScoreList.StudentId 15 where CSharp<@CSharp or SQLServerDB<@DB --顯示結果列表 16 select @AbsentCount=count(*) from Students 17 where StudentId not in(select StudentId from ScoreList) --查詢缺考總人數 18 select @FailedCount=count(*) from ScoreList 19 where CSharp<@CSharp or SQLServerDB<@DB --查詢不及格總人數 20 goView Code
呼叫帶輸出引數的儲存過程
輸出引數在使用前要首先定義,呼叫時也要使用output
1 use StudentManager 2 go 3 --呼叫帶引數的儲存過程 4 declare @AbsentCount int,@FailedCount int --首先定義輸出引數 5 exec usp_ScoreQuery4 @AbsentCount output,@FailedCount output 6 --使用反饋的結果 7 select 缺考總數=@AbsentCount,不及格總數=@FailedCountView Code
自定義儲存過程
1 use StudentManager 2 go 3 if exists(select * from sysobjects where name='usp_ScoreQuery') 4 drop procedure usp_ScoreQuery 5 go 6 create procedure usp_ScoreQuery 7 8 as 9 --查詢考試資訊 10 select Students.StudentId,StudentName,ClassName,ScoreSum=(SQLServerDB+CSharp) from Students 11 inner join StudentClass on Students.ClassId=StudentClass.ClassId 12 inner join ScoreList on Students.StudentId=ScoreList.StudentId 13 order by ScoreSum DESC 14 --統計分析考試資訊 15 select ClassName,C#Avg=AVG(CSharp),DBAvg=AVG(SQLServerDB) 16 from StudentClass 17 inner join Students on StudentClass.ClassId=Students.ClassId 18 inner join ScoreList on ScoreList.StudentId=Students.StudentId 19 group by ClassName 20 go 21 22 exec usp_ScoreQuery --呼叫儲存過程 23 24 25 --if exists(select * from sysobjects where name='usp_ScoreQuery2') 26 --drop procedure usp_ScoreQuery2 27 --go 28 --create procedure usp_ScoreQuery2 29 --@CSharp int, --引數定義 30 --@DB int 31 --as 32 -- select Students.StudentId,StudentName,C#=CSharp, DB=SQLServerDB from Students 33 -- inner join ScoreList on Students.StudentId=ScoreList.StudentId 34 -- where CSharp<@CSharp or SQLServerDB<@DB 35 --go 36 ----呼叫帶引數的SQL語句 37 --exec usp_ScoreQuery2 60,65 --按照引數順序賦值 38 --exec usp_ScoreQuery2 @DB=65,@CSharp=60 39 40 41 if exists(select * from sysobjects where name='usp_ScoreQuery2') 42 drop procedure usp_ScoreQuery2 43 go 44 create procedure usp_ScoreQuery2 45 @CSharp int=60, 46 @DB int=60 47 as 48 select Students.StudentId,StudentName,C#=CSharp, DB=SQLServerDB from Students 49 inner join ScoreList on Students.StudentId=ScoreList.StudentId 50 where CSharp<@CSharp or SQLServerDB<@DB 51 go 52 --呼叫帶引數的SQL語句 53 exec usp_ScoreQuery2 65 54 exec usp_ScoreQuery2 @DB=65 55 56 exec usp_ScoreQuery2 default,65 57 exec usp_ScoreQuery2 58 59 60 if exists(select * from sysobjects where name='usp_ScoreQuery4') 61 drop procedure usp_ScoreQuery4 62 go 63 create procedure usp_ScoreQuery4 64 @AbsentCount int output,--缺考總人數 65 @FailedCount int output,--不及格總人數 66 @CSharp int=60, 67 @DB int=60 68 as 69 select Students.StudentId,StudentName,C#=CSharp, DB=SQLServerDB from Students 70 inner join ScoreList on Students.StudentId=ScoreList.StudentId 71 where CSharp<@CSharp or SQLServerDB<@DB 72 73 select @AbsentCount=COUNT(*) from Students 74 where StudentId not in(Select StudentId from ScoreList) 75 select @FailedCount=COUNT(*) from ScoreList 76 where CSharp<@CSharp or SQLServerDB<@DB 77 go 78 --呼叫帶輸出引數的儲存過程 79 declare @AbsentCount int,@FailedCount int --首先定義輸出引數 80 exec usp_ScoreQuery4 @AbsentCount output,@FailedCount output 81 --讀取輸出引數 82 select 缺考總數=@AbsentCount,不及格總數=@FailedCountView Code
END