视图是可视化的表。
本章讲解如何创建、更新和删除视图。
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]AS
SELECT
ProductID,ProductNameFROM
ProductsWHERE
Discontinued=No
我们可以查询上面这个视图:
SELECT * FROM [Current Product List]
Northwind 样本数据库的另一个视图会选取 Products 表中所有单位价格高于平均单位价格的产品:
CREATE VIEW
[Products Above Average Price]AS
SELECT
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]AS
SELECT 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'
SQL 更新视图
您可以使用下面的语法来更新视图:
SQL CREATE OR REPLACE VIEW Syntax 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 命令来删除视图。
SQL DROP VIEW Syntax DROP VIEW view_name
视图在数据库开发过程中是非常重要的,对提高查询速度有很大的提高。因此我们的学会创建视图,并且有效的使用视图。 (1)表准的SQL视图 标准视图比较简单,大家也都在使用,在此就不垒述了。 (2)使用动态视图 标准视图有一个严重的局限性,那就是标准视图不支持参数。俗话说“法网恢恢,疏而不漏”,呵呵,我们也可以变通的使用带参数的视图。实现方法是我们把一个用户定义的表值函数当作支持参数的动态视图使用: CREATE FUNCTION fnTestView (@m_id int) RETURNS TABLE AS RETURN (select * from 视图名称 where 条件=@m_id) 这样可以在Select语句的From子句中引用他们,用法: Select * from fnTestView(2)
(3)使用索引视图 我们在使用视图的时候有时想怎么能给视图加索引呢,其实,视图和普通的表一样可以添加索引,当SQL Server必须联合很多表时,这项技术可以大大提高Select语句的性能。 当在视图上创建一个唯一聚集索引(unique clusterd index)时,SQL Server将物化这个视图。看下面的例子: CREATE VIEW dbo.vtUsers WITH SCHEMABINDING AS SELECT dbo.tUsers.userid, dbo.tUsers.username, dbo.tUsers.password, dbo.tUsers.question, dbo.tUsers.answer, dbo.tUsers.email, dbo.tUsers.realname, dbo.tUsers.sex, dbo.tUsers.birthday, dbo.tUsers.country, dbo.tUsers.city, dbo.tUsers.address, dbo.tUsers.zip, dbo.tUsers.tele, dbo.tUsers.exdate, dbo.tUsers.totalfund, dbo.tUsers.ordertotal, dbo.tUsers.jifen, dbo.tUsers.pid, dbo.tUsers.agentid, dbo.tUsers.agentid2, dbo.tUsers.agentid3, dbo.tUsers.status, dbo.tUsers.checkmod, dbo.tUsers.account, dbo.tUsers.bank, dbo.tUsers.logip, dbo.tUsers.sitename, dbo.tUserInfo.siteurl FROM dbo.tUsers INNER JOIN dbo.tUserInfo ON dbo.tUsers.userid = dbo.tUserInfo.userid WHERE dbo.tUserInfo.UserID >20
CREATE UNIQUE CLUSTERED INDEX idxvtUser ON vtUsers(userid)
尽管这个索引只引用了列的一个子集,但是这个索引包含叶级别节点中的所有列(每个聚集索引也都是这样)。 和标准视图一样索引视图的创建和使用也都是有限制的。一个标准视图转换为一个索引视图必须遵守以下规则: A.视图必须使用With Schemabinding选项来创建; B.在这个视图中不能使用其他视图、导出表、行集函数或自查询,也就是说只能使用表; C.视图所用到的基本表必须和视图属于同一个所有者; D.视图只能链接同一个数据库中的表; E.视图不能包含一个外部链接或自链接,也就是说在链接表时只能使用INNER JOIN并且INNER JOIN前后不能使同一个表,不能使用LEFT(RIGHT) JOIN 或者 LEFT (RIGHT) OUTER JOIN ;看下面的例子: 比如说创建了下面的视图(自链接): CREATE VIEW dbo.vtUsers WITH SCHEMABINDING AS SELECT dbo.tUsers.userid, dbo.tUsers.username, dbo.tUsers.password, dbo.tUsers.question, dbo.tUsers.answer, dbo.tUsers.email, dbo.tUsers.realname FROM dbo.tUsers Inner join dbo.tUsers as t ON dbo.tUsers.userid = t.userid 这个视图是可以创建的,但是在创建索引时CREATE UNIQUE CLUSTERED INDEX idxvtUser ON vtUsers(userid) 就会出错了; 再看下面的视图(外部连接): CREATE VIEW dbo.vtUsers WITH SCHEMABINDING AS SELECT dbo.tUsers.userid, dbo.tUsers.username, dbo.tUsers.password, dbo.tUsers.question, dbo.tUsers.answer, dbo.tUsers.email, dbo.tUsers.realname FROM dbo.tUsers LEFT OUTER JOIN dbo.tUserInfo ON dbo.tUsers.userid = dbo.tUserInfo.userid 在创建索引时也会出错的。 F. 视图不能包含UNION子句、TOP子句、ORDER BY子句、Having子句、Rollup子句、Cube子句、compute子句、Compute By子句或Distinct关键字; G. 视图不允许使用某些集合函数,如:Count(*)可以使用count_big(*)代替、avg()、max()、min()、stdev()、stdevp()、var()或varp()等; H. 视图不能使用Select * 这样的语句,也就是说视图的所有字段都必须显示指定; I. 视图不能包含Text、ntext、image类型的列; J. 如果视图包含一个Group By子句,那么他必须在Select列中包含count_big(*); K. 视图中的所有标和用户自定义的函数都必须使用两段式名来引用,即所有者.表或函数名称; L. 所有的基本表和视图都必须使用 Set Ansi_Nulls On 创建; M. 在创建索引时或创建索引后执行IUD时,必须显示或隐式地执行: Set ANSI_NULLS ON SET ANSI_PADDING ON SET ANSI_WARNINGS ON SET ARITHABORT ON SET CONCAT_NULL_YIELDS_NULL ON SET QUOTED_IDENTIFIER ON SET NUMERIC_ROUNDABORT OFF 各个选项的有关信息或意义,可以查阅SQL Server的联机丛书,这里就不再介绍了; N. 索引视图只有在SQL Server2000的企业版或开发版或者更高的版本中才能创建。 如果一个视图可以添加唯一聚集索引,那么在添加了唯一聚集索引之后,该视图也可以像数据库表一样添加非聚集索引,CREATE INDEX idxvtUsers ON vtUsers(username,realname)。
关于视图大家可能还有更多好的处理方法和建议,希望大家补充。