视图(一) 概述和Order By的误区

视图由一个查询定义,可以当作一个表使用,就是一个命名的虚拟表。建立和使用视图的时候有几个要注意的地方。
1.         视图中的数据没有物理表现形式,除非在上面建立索引,当在没有建立索引的视图中执行查询等操作时,实际访问的基础表。
2.         不能在视图定义中使用Order By,除非定义中包含Top和FOR XML说明符。
3.         所有的结果列必须有名称。
4.         所有的结果列的名称必须唯一。
5.         视图被认为是一个表,表是一个逻辑实体,表中的行没有顺序。

下面是一个非常简单的建立视图的例子。
SET NOCOUNT ON
USE EDUDB
IF OBJECT_ID('vw_TopicCourseInfo') IS NOT NULL
Drop VIEW dbo.vw_TopicCourseInfo
GO
Create VIEW dbo.vw_TopicCourseInfo WITH ENCRYPTION,SCHEMABINDING
AS
Select Topic_ID,Topic_Name
FROM dbo.Topic AS T
Where EXISTS
    (Select 1 FROM dbo.Course AS C
    Where T.Topic_ID=C.Course_Topic_ID)
GO
由于在视图建立的时候使用了SCHEMABINDING 参数,所有在建立视图的语句必须满足下面的两个条件,1 使用的对象必须使用由两部分构成的名称。2 不能在Select列表中使用*,所有的列名称必须进行显示的标记。
在Exists谓词中大家可以放心的使用*进行查询,并且不会降低性能,原因非常的简单,优化器知道EXISTS谓词不需要引用行的特定属性,他关心的只是行是否真的存在,他会完全忽略Select列表。有一个非常简单的方法证明Select列表被忽略,在Select指定一个将会输出错误的表达式,我们只要观察输出的结果就可以知道优化器是否计算了这个错误的表达式。
IF EXISTS(Select 1/0)
    PRINT 'NO ERROR'
ELSE
PRINT 'ERROR'
输出的结果是 NO ERROR
视图中的ORDER BY
下面时一个使用ORDER BY的简单的例子,修改上面建立的视图。
Alter VIEW dbo.vw_TopicCourseInfo WITH ENCRYPTION,SCHEMABINDING
AS
Select TOP(100) PERCENT Topic_ID,Topic_Name,Topic_Desc
FROM dbo.Topic AS T
Where EXISTS
    (Select 1 FROM dbo.Course AS C
    Where T.Topic_ID=C.Course_Topic_ID)
    orDER BY Topic_Name
GO

许多的程序员在建立视图的时候喜欢使用ORDER BY对输出的数据进行排序,在SQL Server 2000中可能会得到正确的数据,但是在2005中将不能得到排序的数据,这种效果完全可以在对视图的外部查询中实现,非常的简单,视图的查询不允许使用ORDER BY是有原因的。视图表示一个逻辑实体,不像游标那样的可以对行进行排序,一个非常简单的道理,表中的行是没有顺序的。TOP 和ORDER BY以及FOR XML和ORDER BY可以出现在视图的定义中,单独的ORDER BY却是不可以的。

其实创建排序视图的本身就是错误的,因为视图是一个表,但是表是不会对行进行排序的。SQL SERVER 2005联机丛书中的解释是“在视图,内联函数,派生表和子查询的定义中使用ORDER BY时,子句只用于TOP子句返回的行,ORDER BY不保证在查询这些构造时得到正确的结果,除非在查询本身也指定了ORDER BY。”,在对视图的外部查询时使用ORDER BY才是正确的处理方式。
原文地址:https://www.cnblogs.com/noviceliu/p/1408434.html