背景:                 
[本书目录] [图书首页] [本书讨论区]  
链接地址:http://www.17xie.com/read-39342.html    注册17xie 一起来写书 实现您的出书梦想!

1.6  视图选项

当你创建或修改视图时,可以指定一些选项,这些选项用于控制视图的行为和功能。ENCRYPTION、SCHEMABINDING和 VIEW_METADATA选项在视图头指定,CHECK OPTION选项则在查询之后指定。

ENCRYPTION

ENCRYPTION选项可用于视图、UDF、存储过程和触发器。如果未指定ENCRYPTION选项,SQL Server在sys.sql_modules(在SQL Server 2000中是syscomments)中以纯文本的形式保存用于定义对象/程序主体的语句。如果指定ENCRYPTION选项,对象的文本将会被混淆,但不要依赖这个选项作为加密机制来保护你的智力成果。人们已经发现了对使用ENCRYPTION选项创建的对象文本进行解密的方法。甚至在SQL Server 2005中,创建对象的文本对于特权用户也是可以访问的,他们通过专用管理员连接(dedicated administrator connection,DAC)可以直接访问数据库文件,或者使用调试器对内存进行访问。关于ENCRYPTION选项的更详细的信息,请参考联机丛书。

SCHEMABINDING

SCHEMABINDING选项把视图或UDF的架构绑定到基对象的架构。如果你使用SCHEMABINDING选项创建视图,SQL Server将不允许删除基对象或修改被引用的列。这个选项对于定义视图的查询有两个语法要求:所有对象必须使用由两部分构成的名称(例如,应该使用dbo.Orders,不能是Orders),而且不能在SELECT列表中使用*,所有的列名称都必须被显式指定。

作为一个使用ENCRYPTION 和SCHEMABINDING选项的示例,下面的代码重新创建我前面使用过的VcustsWithOrders视图。

USE Northwind;

GO

IF OBJECT_ID(‘dbo.VcustsWithOrders’) IS NOT NULL

  DROP VIEW dbo.VcustsWithOrders;

GO

CREATE VIEW dbo.VcustsWithOrders WITH ENCRYPTION, SCHEMABINDING

AS

SELECT CustomerID, CompanyName, ContactName, ContactTitle,

  Address, City, Region, PostalCode, Country, Phone, Fax

FROM dbo.Customers AS C

WHERE EXISTS

  (SELECT 1 FROM dbo.Orders AS O

   WHERE O.CustomerID = C.CustomerID);

GO

注意   如果视图已经存在,使用ALTER VIEW命令比删除后再重建视图要更明智,因为ALTER VIEW可以保持权限。

注意,我在子查询的SELECT列表中用常量1代替了*,这样就符合了SCHEMABINDING选项的要求。

尝试获取视图的文本:

EXEC sp_helptext ‘dbo.VcustsWithOrders’;

你会得到下面的输出:

The text for object ‘dbo.VcustsWithOrders’ is encrypted.

试着修改一个被引用列:

ALTER TABLE dbo.Customers DROP COLUMN Address;

你会收到下面的错误:

Msg 5074, Level 16, State 1, Line 1

The object ‘VcustsWithOrders’ is dependent on column ‘Address’.

Msg 4922, Level 16, State 9, Line 1

ALTER TABLE DROP COLUMN Address failed because one or more objects access this column.

CHECK OPTION

使用WITH CHECK OPTION创建的视图会防止与视图的查询筛选器有冲突的INSERT 和UPDATE语句。没有该选项,视图可以接受不符合查询筛选器的修改。例如,VcustsWithOrders视图接受下面的INSERT,即使代码会插入尚未发生订单的新消费者。

INSERT INTO dbo.VcustsWithOrders(CustomerID, CompanyName)

  VALUES(N’ABCDE’, N’Company ABCDE’);

新的消费者被添加到Customers表中,但很明显,当查询该视图时,你找不到这个新的消费者,因为视图只包含发生过订单的消费者:

SELECT CustomerID, CompanyName

FROM dbo.VcustsWithOrders

WHERE CustomerID = N’ABCDE’;

该查询返回一个空集。

如果你直接查询Customers表,就可以看到这个新增的消费者了。

SELECT CustomerID, CompanyName

FROM dbo.Customers

WHERE CustomerID = N’ABCDE’;

该查询返回消费者ABCDE相关的信息。

接下来运行下面的代码为视图的定义中添加CHECK OPTION选项。

ALTER VIEW dbo.VcustsWithOrders WITH ENCRYPTION, SCHEMABINDING

AS

SELECT CustomerID, CompanyName, ContactName, ContactTitle,

  Address, City, Region, PostalCode, Country, Phone, Fax

FROM dbo.Customers AS C

WHERE EXISTS

  (SELECT 1 FROM dbo.Orders AS O

   WHERE O.CustomerID = C.CustomerID)

WITH CHECK OPTION;

GO

注意   修改视图时,必须重新指定所有需要保留的选项,在我们的示例中包括ENCRYPTION 和SCHEMABINDING。如果你在ALTER语句中未指定这些选项,它们将不会有效。

现在尝试插入与筛选器冲突的行。

INSERT INTO dbo.VcustsWithOrders(CustomerID, CompanyName)

  VALUES(N’FGHIJ’, N’Company FGHIJ’);

你会收到下面的错误:

Msg 550, Level 16, State 1, Line 1

The attempted insert or update failed because the target view either specifies WITH CHECK OPTION or spans a view that specifies WITH CHECK OPTION and one or more rows resulting from

the operation did not qualify under the CHECK OPTION constraint.

The statement has been terminated.

VIEW_METADATA

只有当客户端的请求最终会生成以视图为目标的T-SQL代码时,SQL Server才可以控制该请求通过视图来的查询或修改数据。但是,当客户端通过DB-Library、ODBC或OLEDB API请求浏览模式(browse-mode)的元数据时会出现一些问题。浏览模式元数据是SQL Server向客户端API返回的基表(base table)和结果集列的元数据。当然,如果客户端选择用基表而不是视图作为目标来构造语句,用户的请求可能不会按预期的那样执行。

假设用户拥有对一个视图的权限,但没有对其基础表(underlying table)的权限。该用户尝试对视图执行一些操作。如果客户端工具对基础表构造的语句需要请求浏览模式的元数据,该语句将会因为违背安全(security violation)而失败。另一方面,如果用户尝试通过视图修改数据,而该操作又与视图上定义的CHECK OPTION有冲突,这种操作只有直接提交到基础表,才有可能成功。

SQL Server 2000中的企业管理器(EM)就是这样的一个工具,当你通过视图以图形化形式操作数据时(右键单视图名称,然后选择打开视图并返回所有数据),它会请求浏览模式的元数据信息。如果你在操作视图数据时跟踪企业管理器提交到SQL Server中的操作,你会发现操作实际上是把基础表作为目标提交的。例如,使用企业管理器通过VcustsWithOrders尝试插入一个消费者。在CustomerID列指定FGHIJ并把公司FGHIJ作为CompanyName列的值。你会发现尽管该尝试应该因违反CHECK OPTION而失败,但实际上该操作可以被接受,该行将被添加到Customers表。如果你跟踪企业管理器对SQL Server提交的操作,就会明白它为什么会成功。跟踪中会显示下面的语句:

exec sp_executesql N’INSERT INTO “Northwind”.”dbo”.”Customers” (“CustomerID”,”CompanyName”)

VALUES (@P1,@P2)’, N’@P1 nvarchar(5),@P2 nvarchar(40)’,

N’FGHIJ’, N’Company FGHIJ’

EM构造的语句是针对Customers表而不是视图的。SQL Server Management Studio (SSMS)部分地解决了这个问题。如果在视图/查询设计器结果面板中进行操作,类似的尝试还是可以成功执行。但如果在由“打开视图”产生的面板中进行操作,将会失败。对于后者,你会在跟踪中发现下面的语句,它表明操作是提交给视图的。

exec sp_executesql N’INSERT INTO VcustsWithOrders(CustomerID, CompanyName) VALUES (@Customer ID, @CompanyName)’,N’@CustomerID

nvarchar(5),@CompanyName nvarchar(13)’,@CustomerID=N’FGHIJ’,@CompanyName=N’Company FGHIJ’

如果你希望客户端API请求浏览模式(browse mode)的元数据时SQL Server发送视图的元数据信息,而不是发送基础表的元数据信息,可以在创建或修改视图时指定VIEW_METADATA选项,就像这样。

ALTER VIEW dbo.VcustsWithOrders

  WITH ENCRYPTION, SCHEMABINDING, VIEW_METADATA

AS

SELECT CustomerID, CompanyName, ContactName, ContactTitle,

  Address, City, Region, PostalCode, Country, Phone, Fax

FROM dbo.Customers AS C

WHERE EXISTS

  (SELECT 1 FROM dbo.Orders AS O

   WHERE O.CustomerID = C.CustomerID)

WITH CHECK OPTION;

GO

完成后,执行下面的代码进行清理:

USE Northwind;

GO

DELETE FROM dbo.Customers

WHERE CustomerID IN(N’ABCDE’, N’FGHIJ’);

GO

IF OBJECT_ID(‘dbo.VcustsWithOrders’) IS NOT NULL

  DROP VIEW dbo.VcustsWithOrders;

GO


字数:5215    最后更新:8个月以前 [03-18 15:19]happyskynet 修改
本页编辑者:happyskynet  
[前一页]:1.5 更新视图  [后一页]:1.7 索引视图(Indexe…
[在本页中加入书签] [收藏本书] [推荐本书]
  17xie论坛 > 本书讨论区 > 本页评论   (共0条)
发表评论

用户名称 匿名发表
评论内容
验证码

关于我们 | 版权声明 | 免责声明 | 诚聘英才 | 联系我们 | 合作伙伴 | 友情链接 | 广告合作 | 提交意见
Copyright © 2007 17xie.com 互联网协同写书平台 京ICP备08002671号