1. 程式人生 > 其它 >MS SQL高階——檢視與儲存過程

MS SQL高階——檢視與儲存過程

檢視與儲存過程

什麼是檢視

 檢視的概念

  • 是儲存在伺服器端的一個查詢塊,是一張虛擬表。
  • 表示一張表的部分資料或多張表的綜合資料。
  • 其結構和資料是建立在對錶的查詢基礎上。
  • 檢視的使用,跟對普通的表的查詢使用完全一樣。

檢視中不存放資料

  • 資料存放在檢視所引用的原始表中。

表檢視的多樣性

  • 一個或多個原始表,根據不同使用者的不同需求,可以建立不同的檢視。

檢視的用途

  • 篩選表中的行。
  • 防止未經許可的使用者訪問敏感資料。
  • 降低資料庫的複雜程度。
  • 將多個物理資料庫抽象為一個邏輯資料庫。

如何建立檢視

使用管理器建立檢視

T-SQL語句管理檢視

使用T-SQL語句建立檢視

CREATE VIEW
view_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,
11 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.ClassId
16 go 17 --使用檢視查詢 18 select * from view_ScoreQuery
View Code

使用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_procedures  
View 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 go
View 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,不及格總數=@FailedCount
View 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,不及格總數=@FailedCount
View Code

END