您的位置:首页 > 数据库

细说Sql Server中的视图(上)(更新)

2009-06-16 23:50 323 查看
1,什么是视图?

2,为什么要用视图;

3,视图中的ORDERBY;

4,刷新视图;

5,更新视图;

6,视图选项;

7,索引视图;

细说SqlServer中的视图(下)应大家要求已在“细说SqlServer中的视图(上)”中添加“为什么要用视图”一小节。

1.什么是视图

视图是由一个查询所定义的虚拟表,它与物理表不同的是,视图中的数据没有物理表现形式,除非你为其创建一个索引;如果查询一个没有索引的视图,SqlServer实际访问的是基础表。

如果你要创建一个视图,为其指定一个名称和查询即可。SqlServer只保存视图的元数据,用户描述这个对象,以及它所包含的列,安全,依赖等。当你查询视图时,无论是获取数据还是更新数据,Sqlserver都用视图的定义来访问基础表;

视图在我们日常操作也扮演着许多重要的角色,比如可以利用视图访问经过筛选和处理的数据,而不是直接访问基础表,以及在一定程度上也保护了基础表。

我们在创建视图的时候,也要遵守三个规则:

不能在视图定义中指定ORDERBY,除非定义中包含Top或ForXml说明;
所有的列必须有列名;
这些所有的列名必须唯一;

对于视图表中在没有top或forxml说明的情况下,不能有Orderby语句,这是因为视图被认为是一个表,表是一个逻辑的实体,它的行是没有顺序的。视图中所有列必须有列名,且唯一的情况我想大家都理解;


下面的sql语句表示创建一个简单的视图:

CREATEVIEWdbo.V1
AS
SELECTCustomerID,CompanyNameFROMCustomers
WHEREEXISTS(SELECT*FROMOrdersWHERECustomers.CustomerID=Orders.CustomerID)


.csharpcode,.csharpcodepre
{
font-size:small;
color:black;
font-family:consolas,"CourierNew",courier,monospace;
background-color:#ffffff;
/*white-space:pre;*/
}
.csharpcodepre{margin:0em;}
.csharpcode.rem{color:#008000;}
.csharpcode.kwrd{color:#0000ff;}
.csharpcode.str{color:#006080;}
.csharpcode.op{color:#0000c0;}
.csharpcode.preproc{color:#cc6633;}
.csharpcode.asp{background-color:#ffff00;}
.csharpcode.html{color:#800000;}
.csharpcode.attr{color:#ff0000;}
.csharpcode.alt
{
background-color:#f4f4f4;
width:100%;
margin:0em;
}
.csharpcode.lnum{color:#606060;}
2.为什么要使用视图(更新)
SqlServer既然给我们提供这样的对象,就一定有它的作用。而我们在使用视图上,要么用的过多,要么用的不够,所以一部分人建议不要用视图,而一部分人又建议少用。那我们听谁的呢?
其实我们要是掌握了用视图的目的,就能在正确的地方,用正确的视图;那么视图能给我们解决什么问题呢?
1,为最终用户减少数据库呈现的复杂性。客户端只要对视图写简单的代码,就能返回我所需要的数据,一些复杂的逻辑操作,放在了视图中来完成;
2,防止敏感的列被选中,同时仍然提供对其他重要数据的访问;
3,对视图添加一些额外的索引,来提高查询的效率;
视图其实没有改变任何事情,只是对访问的数据进行了某种形式的筛选。考虑一下视图的作用,你应该能看到视图的概念如何为缺乏经验的用户简化数据(只显示他们关心的数据),或者不给予用户访问基础表的
权利,但授予他们访问不包含敏感数据视图的权力,从而提前隐藏敏感数据。
要知道,在默认的情况下,视图没有做什么特殊的事情。视图就好象一个查询那样从命令行运行(这里不存在任何形式的预先优化),这意味着在数据请求和将被交付的数据之间多加了一层开销。这表明视图绝不可能像
只是直接运行底层SELECT语句那样快。不过,视图存在有一个原因--这就是它的安全性或为用户所做的简化,在你的需要和开销之间权衡,找到最适合特定情况的解决方案。
3.视图中的ORDERBY
视图表示一个逻辑实体,它与表非常类似;
如果我们在上面的创建的sql语句中加一个OrderBY语句,看看有什么效果:

ALTERVIEWdbo.V1
AS
SELECTCustomerID,CompanyNameFROMCustomers
WHEREEXISTS(SELECT*FROMOrdersWHERECustomers.CustomerID=Orders.CustomerID)
ORDERBYCompanyName


.csharpcode,.csharpcodepre
{
font-size:small;
color:black;
font-family:consolas,"CourierNew",courier,monospace;
background-color:#ffffff;
/*white-space:pre;*/
}
.csharpcodepre{margin:0em;}
.csharpcode.rem{color:#008000;}
.csharpcode.kwrd{color:#0000ff;}
.csharpcode.str{color:#006080;}
.csharpcode.op{color:#0000c0;}
.csharpcode.preproc{color:#cc6633;}
.csharpcode.asp{background-color:#ffff00;}
.csharpcode.html{color:#800000;}
.csharpcode.attr{color:#ff0000;}
.csharpcode.alt
{
background-color:#f4f4f4;
width:100%;
margin:0em;
}
.csharpcode.lnum{color:#606060;}


运行该语句将会失败,回收到以下的提示:



Msg1033,Level15,State1,ProcedureV1,Line5
除非另外还指定了TOP或FORXML,否则,ORDERBY子句在视图、内联函数、派生表、子查询和公用表表达式中无效。

根据提示,ORDERBy也不是不能用,只有指定了Top或forxml语句后,ORDERBY才能使用,如:

ALTERVIEWdbo.V1
AS
SELECTTOP(10)CustomerID,CompanyNameFROMCustomers
WHEREEXISTS(SELECT*FROMOrdersWHERECustomers.CustomerID=Orders.CustomerID)
ORDERBYCompanyName


.csharpcode,.csharpcodepre
{
font-size:small;
color:black;
font-family:consolas,"CourierNew",courier,monospace;
background-color:#ffffff;
/*white-space:pre;*/
}
.csharpcodepre{margin:0em;}
.csharpcode.rem{color:#008000;}
.csharpcode.kwrd{color:#0000ff;}
.csharpcode.str{color:#006080;}
.csharpcode.op{color:#0000c0;}
.csharpcode.preproc{color:#cc6633;}
.csharpcode.asp{background-color:#ffff00;}
.csharpcode.html{color:#800000;}
.csharpcode.attr{color:#ff0000;}
.csharpcode.alt
{
background-color:#f4f4f4;
width:100%;
margin:0em;
}
.csharpcode.lnum{color:#606060;}

但是,并不建议在视图中使用ORDERBY,这是因为视图表示一个表,而对于表来说,是不会有排序的;所以建议在查询视图的时候,用ORDERBY;

SQLServer2005联机丛书有一段这样的描述:“在视图、内联函数、派生表或子查询的定义中使用ORDERBY字句,子句只能用户确定TOP子句返回的行。ORDERBY不保证在查询这些构造时得到有序结果,除非在查询本省也指定了ORDERBY.”

4.刷新视图


我在上面说过,视图会保存元数据,列,安全,以及依赖等信息,如果我们把基础表的架构更改了,并不会直接反映到视图上来;更改架构后,使用sp_refreshview存储过程刷新视图的元数据是一个好习惯;

比如我们创建了一个表T1和一个T1的视图V1,然后更改T1,再看V1的结果:

首先创建表T1:

IFOBJECT_ID('T1')ISNOTNULL
DROPTABLET1
CREATETABLET1(col1INT,col2INT)
INSERTINTOT1(col1,col2)VALUES(1,2)
GO


.csharpcode,.csharpcodepre
{
font-size:small;
color:black;
font-family:consolas,"CourierNew",courier,monospace;
background-color:#ffffff;
/*white-space:pre;*/
}
.csharpcodepre{margin:0em;}
.csharpcode.rem{color:#008000;}
.csharpcode.kwrd{color:#0000ff;}
.csharpcode.str{color:#006080;}
.csharpcode.op{color:#0000c0;}
.csharpcode.preproc{color:#cc6633;}
.csharpcode.asp{background-color:#ffff00;}
.csharpcode.html{color:#800000;}
.csharpcode.attr{color:#ff0000;}
.csharpcode.alt
{
background-color:#f4f4f4;
width:100%;
margin:0em;
}
.csharpcode.lnum{color:#606060;}

然后创建T1的视图V1:

CREATEVIEWV1
AS
SELECT*FROMT1


.csharpcode,.csharpcodepre
{
font-size:small;
color:black;
font-family:consolas,"CourierNew",courier,monospace;
background-color:#ffffff;
/*white-space:pre;*/
}
.csharpcodepre{margin:0em;}
.csharpcode.rem{color:#008000;}
.csharpcode.kwrd{color:#0000ff;}
.csharpcode.str{color:#006080;}
.csharpcode.op{color:#0000c0;}
.csharpcode.preproc{color:#cc6633;}
.csharpcode.asp{background-color:#ffff00;}
.csharpcode.html{color:#800000;}
.csharpcode.attr{color:#ff0000;}
.csharpcode.alt
{
background-color:#f4f4f4;
width:100%;
margin:0em;
}
.csharpcode.lnum{color:#606060;}


在现实实践中,要避免在视图中的SELECT语句中使用*,在这只是演示。如果你查询视图V1就会出现以下结果:




接下来,我们对表T1添加一列col3:

ALTERTABLET1ADDcol3INT


.csharpcode,.csharpcodepre
{
font-size:small;
color:black;
font-family:consolas,"CourierNew",courier,monospace;
background-color:#ffffff;
/*white-space:pre;*/
}
.csharpcodepre{margin:0em;}
.csharpcode.rem{color:#008000;}
.csharpcode.kwrd{color:#0000ff;}
.csharpcode.str{color:#006080;}
.csharpcode.op{color:#0000c0;}
.csharpcode.preproc{color:#cc6633;}
.csharpcode.asp{background-color:#ffff00;}
.csharpcode.html{color:#800000;}
.csharpcode.attr{color:#ff0000;}
.csharpcode.alt
{
background-color:#f4f4f4;
width:100%;
margin:0em;
}
.csharpcode.lnum{color:#606060;}

然后再次查询视图V1,你想这时的结果是三列呢,还是而列呢?答案是二列。T1架构的改变,并没有影响到视图的元数据中,这时候,如果我们要刷新一下视图V1,我们就可以用:EXECsp_refreshviewV1命令,再次查询,V1的结果就是三列了。


不写了,困了,明天再补全,就分上下二节吧


兴百放


参考文献:《T-SQL程序设计》

Tag标签:视图,SqlServer,View,刷新视图,更新视图,索引视图
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐
章节导航