7.5 視圖的定義
視圖是從一個或幾個基表(或視圖)導出的虛擬表。視圖中行和列數據來源於由定義視圖的查詢所引用的表,並且在引用視圖時動態生成
7.5.1 視圖概念
- 視圖是從一個或者多個表及其他視圖中通過SELECT語句導出的虛擬表。視圖與數據表一樣包含一些列帶有名稱的列和行的數據,但是,視圖所對應數據的行和列數據來自定義視圖的查詢所引用的表,並且在引用視圖時動態生成。
- 視圖的行爲和數據表類似,可以對其進行查看、修改和刪除,也可通過視圖實現對基表數據的查詢與修改。
- 視圖爲數據庫用戶提供了很多的便利,主要包括以下幾個方面。
- 簡化數據查詢和處理。
- 屏蔽數據庫的複雜性。
- 安全性。可以只授予用戶訪問視圖的權限,而不授予訪問表的權限,這樣就提高了數據庫的安全性。
7.5.2 創建視圖
- 使用SQL Server Management Studio創建視圖
- 使用Transact-SQL語句創建視圖
語法格式如下:
create view [database_name.][schema_name.]
view_name[(column[,…n])]
[with view_attribute[,…n]]
as select_statement
[with check option]
其中view_attribute定義爲:
{encryption|schemabinding|view_metadata}
例7.11
編程在 teaching 數據庫中創建一個名稱爲 v_course 的視圖,包含所有類別爲“必修”的課程信息。
use teaching
go
create view v_course
as select * from course
where type=‘必修’
例7.12
編程在 teaching 數據庫中創建一個名稱爲 v_final 的視圖,包含學生學號、姓名、課程號、課程名和期末成績,按學號升序排序,相同學號的記錄按課程號升序排序。
create view v_final as
select top(100) percent student.studentno,
student.sname,course.courseno,course.cname,score.final
from student,course,score
where student.studentno=score.studentno and
course.courseno=score.courseno
order by student.studentno,course.courseno
例7.13
編程在 teaching 數據中創建一個名稱爲 v_max 的視圖,查詢每個班最高分的課程名和分數,按班級號升序排序。
create view v_max as
select top 10 classno,cname,max(final) as max
from student s,score sc,course c
where sc.courseno=c.courseno and
s.studentno=sc.studentno and final is not null
group by classno,cname
order by classno - 通過視圖查看數據
語法格式如下:
select * from view_name
例7.14
通過 v_final 和 v_course 視圖查詢所有學生的學號、姓名和必修課的總學分。
select studentno as ‘學號’,sname as ‘姓名’,sum(credit) as ‘必修課總學分’
from v_final,v_course
where v_final.courseno=v_course.courseno
group by studentno,sname
7.5.3 查看視圖信息
- 使用系統存儲過程查看視圖信息
- sp_help:用於顯示數據庫對象或數據類型的基本信息。語法格式如下:
sp_help [[@objname=]‘name’] - sp_helptext:用於顯示用戶定義規則、默認值、未加密的存儲過程、觸發器、視圖等數據對象的定義信息,語法格式如下:
sp_helptext [@objname=]‘name’ - sp_depends:用於顯示有關數據庫對象依賴關係的信息。語法格式如下:
sp_depends[@objname=]‘object’
- 使用系統表查看視圖信息
例7.15
利用 sysobjects 和 syscomments 兩個系統表查看 v_avg 視圖的名稱、ID和定義視圖的文本信息。
select
sysobjects.name,sysobjects.id,syscomments.text
from sysobjects,syscomments
where sysobjects.name=‘v_avg’ and
sysobjects.type=‘v’ and
sysobjects.id=syscomments.id
7.6 視圖的修改
7.6.1 在SQL Server Management Studio中修改視圖
- 語法格式如下:
alter view [database_name.][shema_name.]
view_name[(column[,statement [with check option]
例7.16
使用ALTER VIEW語句修改 v_final 視圖,使其包含所有學生姓名、課程名和期末成績,按姓名升序排序。
alter view v_final as
select top(100) percent
student.studentno,sname,cname,final
from student,course,score
where student,course,score
where student.studentno=score.studentno and
course.courseno=score.courseno
order by student.studentno
例7.17
使用ALTER VIEW語句修改v_avg視圖,將其改爲加密方式,以確保視圖的安全性。
alter view v_avg
with encryption as
select top(100)percent student.sname,avg(score.final) as average
from score inner join student on score.studentno=student.studentno
where student.classno=‘090501’ and score.final is not null
group by student.sname having(score.final)>60
order by average desc
–使用系統存儲過程sp_helptext查看已加密視圖的定義信息
exec sp_helptext v_avg
7.6.3 視圖重命名
語法格式如下:
sp_rename[@objname=]‘object_name’,
[@newname=]‘new_name’
[,[@objtype=] ‘object_type’]
例如
exec sp_rename ‘v_成績’,‘v_final’
7.6.4 刪除視圖
語法格式如下:
drop view [schema_name] view_name[…,n][;]
7.7 通過視圖修改數據
- 通過視圖向基表中插入數據
(1)使用INSERT語句向數據表中插入數據時,用戶必須具備插入數據的相關權限。
(2)進行插入操作的視圖只能引用一個基表的列。
(3) 視圖中包含的列必須直接引用表列中的基礎數據,不能通過計算或聚合函數等方式派生。
(4)INSERT語句須爲不允許爲空值,且沒有DEFAULT定義的基表中的所有列指定值。這將確保基表中所有需要值的列都可以獲取值。
(5)在基表中插入的數據必須符合在相關列上定義的約束條件,如是否爲空、約束及默認值定義等。
(6)視圖中不能包含DISTINCT、GROUP BY或HAVING子句。
(7)如果在視圖定義中使用了WITH CHECK OPTION子句,則該子句將檢查插入的數據是否符合視圖定義中SELECT語句所設置的條件,如果插入的數據不符合該條件,SQL Server會拒絕插入數據,並顯示錯誤。
例7.18
通過視圖 v_course 向基表 course 中插入數據 (‘c05129’, ‘數據庫編程’, ‘必修’, 64, 4)。
insert into v_course
values(‘c05129’,‘數據庫編程’,‘必修’,64,4)
select * from course
例7.19
編程在teaching數據中創建一個名稱爲v_sex的視圖,包含所有性別爲“女”的學生的學號、姓名、性別、出生日期和班級編號,需限制插入數據中性別必須爲“女”。
create view v_sex as
select studentno,sname,sex,birthday,classno
from student
where sex=‘女’ with check option - 通過視圖更新基表中的數據
在視圖上可以使用UPDATE語句實現對於基表中相關記錄的修改,但修改操作必須符合在視圖中插入數據的相關規則,並且需要遵守以下規則:
- 修改視圖中的數據時,不能同時修改兩個或者多個基表。
- 當視圖來自多個基表時,通常只能對非主屬性進行修改操作。
- 視圖中被修改的列必須是直接引用基表的列,不能通過計算或聚合函數等方式派生。
例7.21
通過視圖v_course將基表course課程號爲c05129的課程名稱修改爲’數據庫應用與開發’。
use teaching
update v_course
set cname=‘數據庫應用與開發’
where courseno=‘c05129’
select * from course
例7.22
通過視圖v_final 將基表 score 中學號爲 0925121107 的學生樑欣選修的課程號爲c05129的C語言課程的期末成績修改爲60分。
update v_final set final=60
where studentno=‘0925121107’ and courseno=‘c05109’
select s.studentno,sname,c.courseno,cname,final
from student s course c,score sc
where s.studentno=sc.studentno and c.courseno=sc.courseno
例7.23
通過視圖v_final 將基表student和score中學號爲0925121107,選修的課程號爲c05129的學生姓名修改爲李靜,期末成績修改爲60分。
UPDATE v_final SET sname=‘李靜’,final=60
WHERE studentno=‘0925121107’ AND courseno=‘c05109’
例7.24
通過視圖v_sex刪除基表student中學號爲‘ 0938211038’的學生記錄。
DELETE FROM v_sex
WHERE studentno=‘0938211038’
GO
SELECT * FROM student
例7.25
通過視圖 v_course 刪除基表 course 中課程號爲 c05109 的課程記錄。
DELETE FROM v_course
WHERE courseno=‘c05109’
附件:
使用到的數據庫:
https://pan.baidu.com/s/1Lmbw_qSmC04wnPUUgwSKRA
提取碼:djsz