5. SQL -- 视图

视图是可视化的表。


SQL CREATE VIEW 语句

什么是视图?

在 SQL 中,视图是基于 SQL 语句的结果集的可视化的表。

视图包含行和列,就像一个真实的表。视图中的字段就是来自一个或多个数据库中的真实的表中的字段。我们可以向视图添加 SQL 函数、WHERE 以及 JOIN 语句,我们也可以提交数据,就像这些来自于某个单一的表。

注释:数据库的设计和结构不会受到视图中的函数、where 或 join 语句的影响。


视图是一个虚表,可以用来反映一个或多个表的子集,其内容由一个查询语句定

是一个数据的数据象,并不存数据,只是存了一个查询语

视图引用的表称基表

视图中的数据都来自于基表

视图好后,就可以象普通表格一使用

使用视图实际就是行一个保存在视图中的查询语

SQL CREATE VIEW 语法


CREATE VIEW view_name AS
SELECT column_name(s)
FROM table_name
WHERE condition

注释:视图总是显示最近的数据。每当用户查询视图时,数据库引擎通过使用 SQL 语句来重建数据。

SQL CREATE VIEW 实例

可以从某个查询内部、某个存储过程内部,或者从另一个视图内部来使用视图。通过向视图添加函数、join 等等,我们可以向用户精确地提交我们希望提交的数据。

样本数据库 Northwind 拥有一些被默认安装的视图。视图 "Current Product List"  会从 Products 表列出所有正在使用的产品。这个视图使用下列 SQL 创建:

CREATE VIEW [Current Product List] ASSELECT ProductID,ProductNameFROM ProductsWHERE Discontinued=No

我们可以查询上面这个视图:


SELECT * FROM [Current Product List]

Northwind 样本数据库的另一个视图会选取 Products 表中所有单位价格高于平均单位价格的产品:

CREATE VIEW [Products Above Average Price] ASSELECT ProductName,UnitPriceFROM ProductsWHERE UnitPrice>(SELECT AVG(UnitPrice) FROM Products)

我们可以像这样查询上面这个视图:

SELECT * FROM [Products Above Average Price]

另一个来自 Northwind 数据库的视图实例会计算在 1997 年每个种类的销售总数。请注意,这个视图会从另一个名为 "Product Sales for 1997" 的视图那里选取数据:

CREATE VIEW [Category Sales For 1997] ASSELECT DISTINCT CategoryName,Sum(ProductSales) AS CategorySalesFROM [Product Sales for 1997]GROUP BY CategoryName

我们可以像这样查询上面这个视图:

SELECT * FROM [Category Sales For 1997]

我们也可以向查询添加条件。现在,我们仅仅需要查看 "Beverages" 类的全部销量:

SELECT * FROM [Category Sales For 1997]WHERE CategoryName='Beverages'


视图语法:

create view 视图

[With encryption ]

as select

with encryption给视图文本加密

建一个视图时给视图加密:

A、从表timerecords 中,找出clock_id,emp_id,card_id,sign_time 字段视图

createview v_timeview

asselect clock_id,emp_id,sign_time

fromtimerecords

一般视图命名使用v_开头

查询视图

select* from v_timeview

视图详情:

sp_helpv_timeview

视图文件构:

sp_helptextv_timeview

若加密后,不能使用sp_helptext 看到

B建一个加密的视图:

createview v_timerecords

withencryption

asselect clock_id,emp_id,card_id,sign_time

fromtimeRecords


SQL 更新视图

您可以使用下面的语法来更新视图:

CREATE OR REPLACE VIEW view_name AS
SELECT column_name(s)
FROM table_name
WHERE condition

现在,我们希望向 "Current Product List" 视图添加 "Category" 列。我们将通过下列 SQL 更新视图:

CREATE VIEW [Current Product List] AS
SELECT ProductID,ProductName,Category
FROM Products
WHERE Discontinued=No

SQL 撤销视图

您可以通过 DROP VIEW 命令来删除视图。

DROP VIEW view_name


管理视图

A、修改视图alter view

alterview v_timeview

withencryption

asselect clock_id,emp_id,sign_time

fromtimerecords

B视图drop view

if exists (select 1 from sys.objects

whereobject_id = object_id('v_timerecords') and TYPE = 'v')

print'exists'

elseprint 'not exists'

go

dropveiwv_timerecords

以上句使用if exists 判断视图v_timerecords 是否存在,若存在,视图

查询统对像中的所有视图

select* from sys.objects

whereTYPE = 'v'

 

视图的原

只能在当前数据视图

视图名称与表名近似,但不得相同

视图名称遵循标识符的命名规则

可以基于其他视图建立视图,最多允嵌套32

不能在视图上建立规则、默AFTER 器和全文索引

不能临时视图

一个视图最多只能包含1024

视图时不能使用临时表。

即使表被除,视图仍将保留。

义视图查询不能包含以下句:

ORDER BY

COMPUTE 子句

COMPUTE BY 子句

INTO 关键

 

DEMO建一个临时视图

createview #view

as

selectclock_id,emp_id,SIGN_time

fromtimerecords

返回果:

消息4103级别15,状1,第2

"#view":不允使用临时视图

 

过视图修改数据:

足下列条件,可以使用视图修改表中的数据:

视图FROM 子句中至少包含一个表。

选择列表中没有使用聚合函数或GROUP BYUNIONDISTINCT TOP 子句。

视图选择列表中不包含派生列。派生列:查询的列不是来源于基表,而是另一个查询结根据视图修改数据:

select*

--updatev_timerecords set emp_id = 'abc'

fromv_timerecords

whereISNULL(emp_id,'')=''

 

视图架构:

多表视图:基于多表视图,在更新,只能更新一个表需分更新个表内容

A建多表视图

--student

createtable student

(

sidvarchar(20) primary key,

cnamevarchar(20),

)

go

--course

createtable course

(

sidvarchar(20) ,

courseidint ,

iscorenumeric(5,2)

)

go

--在表中插入数据

insertinto student values('A1001','john')

insertinto student values('A1002','marry')

insertinto student values('A1003','linda')

insertinto course values('A1001',1001,62)

 

insertinto course values('A1001',1005,72)

insertinto course values('A1003',1005,96)

--视图,以studentcourse基表

createview v_wstudentscore

As

selecta.sid,a.cname,b.courseid,b.iscore

fromstudent a inner join course b

on a.sid=b.sid

--*注意:inner join 似于,on 似于where

--**更新视图,更新来自于基表studentname字段和来自于course表的iscore字段的

Updatev_wstudentscore

set cname='martin',iscore=iscore+5

Wheresid='A0001'

返回果:

消息4405级别16,状1,第1

视图或函数'v_wstudentscore' 不可更新,因修改会影响多个基表。

更新个表的列:

Updatev_wstudentscore

--setcname='martin'

set iscore=iscore+5

Wheresid='A1001'

返回果:

(2 行受影响)

--建一个视图汇总emp_id日打卡次数

createview v_sign_cnt

withencryption

as

selectCONVERT(varchar(10),SIGN_TIME,121) as sign_time

,emp_id

,COUNT(sign_time) as cnt

fromTimeRecords

groupby CONVERT (varchar(10),sign_time,121),

emp_id

go

/*当需要查询每工的打卡次数,就不用再写转换函数,统计函数

可直接从视图查询查询速度会快. */

--查询emp_id=P1106077 日打卡次数

select* from v_sign_cnt

whereemp_id = 'P1106077'

--DEMO1:

/*多表视图timerecords eployee

eployee中的emp_id,emp_name,

timerecords中的clock_id,sign_time

要求:eployee.emp_id=timerecords.emp_id */

--MYDB入表employee

select* into employee

fromDemo_DB.dbo.employee

--demo_db入表timerecords

select* into timerecords

fromDemo_DB.dbo.TimeRecords

--视图

createview v_sign

withencryption

as

selecta.emp_id,a.emp_name,b.clock_id,b.sign_time

fromemployee a,timerecords b

wherea.emp_id = b.emp_id

select* from v_sign

--DEMO2:更新视图,修改其中一个工号对应的姓名bcy

updatev_sign

set emp_name = 'bcy'

whereemp_id = 'P1102666'

--demo3:修改其中一个打卡时间

updatev_sign

set sign_time = '2011-06-13 14:00:00'

whereemp_id = 'P1102666'

andsign_time = '2011-06-13 12:56:14.000'

--DEMO4:时对表数据行更新:

updatev_sign

set emp_id = 'abc',clock_id = '101'

whereemp_id = 'P1102666'

返回果:

Msg4405, Level 16, State 1, Line 1

视图或函数 'v_sign' 不可更新修改会影响多个基表

 

分区视图

分区视图将大型表中的数据拆分成小的成表。根据其中一列中的数据,在各个成表之间对数据行分区。个成表的数据范都在分区依据列指定的CHECK 束中定。然后定一个视图,以使用 UNION ALL 定的所有成合成果集。引用该视图SELECT 分区依据列指定搜索条件后,查询优化器将使用 CHECK 束定确定哪个成表包含相行。

DEMODB1 DB2 均有一户资料表,通过视图2 个数据下的客户资接要求A-L 的客DB1 下,M-Z 的客DB2

--1建数据,表及

createdatabase db1

go

use db1

go

Createtable customers (

Customeridvarchar(5) not null,

CompanyNamevarchar(50) not null,

ContactNamevarchar(30) null

CONSTRAINTPK_customers PRIMARY KEY CLUSTERED (Customerid),

CONSTRAINTCK_customerid CHECK (Customerid between 'AAAAA' and 'LZZZZ')

)

createdatabase db2

go

use db2

go

Createtable customers (

Customeridvarchar(5) not null,

CompanyNamevarchar(50) not null,

ContactNamevarchar(30) null,

CONSTRAINTPK_customers PRIMARY KEY CLUSTERED (Customerid),

CONSTRAINTCK_customerid CHECK (Customerid between 'M' and 'ZZZZZ')

)

go

--2视图

use db1

go

createview v_customers as

select* from customers

unionall

select* from db2.dbo.customers

use db2

go

createview v_customers as

select* from db1.dbo.customers

unionall

select* from customers

--写入记录

INSERTINTO v_customers VALUES('AAMAY','FUZHOU COMPANY','MARRY')

INSERTINTO v_customers VALUES('CJOHN','XIMEN COMPANY','MARRY')

INSERTINTO v_customers VALUES('SMITH','SHANGHAI COMPANY','TOM')

INSERTINTO v_customers VALUES('YOUNG','FUJIAN COMPANY','JANE')

INSERTINTO v_customers VALUES('GTOPP','BEJING COMPANY','TOM')

INSERTINTO v_customers VALUES('QUILH','BEJING COMPANY','TOM')

select* from v_customers

--记录

use db1

go

select* from customers

use db2

go

select* from customers

分区视图用于多个服例,将数据分散存放在2台服器上


你可能感兴趣的:(数据库,视图)