前言

上一节我们讨论了视图中的一些限制以及建议等,这节我们讲讲关于在UDF和视图中使用SCHEMABINDING的问题,简短的内容,深入的理解,Always to review the basics。

SCHEMABINDING

在上节中我们讲到在视图创建索引时必须指定SCHEMABINDING,所以我们有必要先去了解下这个知识点再继续往下讲解。SCHEMABINDING到底是什么呢?在视图和UDF中有这个选项,如果在视图和UDF函数中指定了这个选项,那么说明会将视图和UDF严格绑定到数据库对象中去,一来指定此选项可以将其严格绑定到数据库对象中去,二来可以提高查询计划执行的性能。下面我们来看看关于SCHEMABINDING在UDF和视图中的使用。

在UDF中的使用

创建UDF函数有三种方式,我们一一来过一遍。

(1)创建TVF内嵌表值函数

USE TSQL2012
GO IF OBJECT_ID('dbo.GetOrderId') IS NOT NULL
DROP FUNCTION dbo.GetOrderId;
GO CREATE FUNCTION dbo.GetOrderId
(@custid INT) RETURNS TABLE WITH SCHEMABINDING
AS
RETURN
SELECT orderid FROM Sales.Orders WHERE custid = @custid
GO

上述UDF是通过TVF的方式来创建,当需要在里面声明一个临时变量并返回时我们需要像如下操作。

(2)创建标量值函数

USE TSQL2012
GO IF OBJECT_ID('dbo.GetOrderId') IS NOT NULL
DROP FUNCTION dbo.GetOrderId;
GO CREATE FUNCTION dbo.GetOrderId
(@custid INT) RETURNS INT WITH SCHEMABINDING
AS
BEGIN
DECLARE @tempID INT
SELECT @tempID = orderid
FROM Sales.Orders
WHERE custid = @custid;
RETURN @tempID;
END;

当利用UDF来对查询出来的数据进行插入到临时表中时,我们可以像如下操作

(3)创建多语句TVF内嵌表值函数

USE TSQL2012
GO CREATE FUNCTION [UDF]
(@PageNum int, @PageSize int)
RETURNS @TestTable TABLE (RowNumber INT, ID INT, Name VARCHAR())
AS
BEGIN
declare @RowNumber int ;WITH C
As (
SELECT 'RowNumber' = ROW_NUMBER() OVER(ORDER BY id DESC),
orderid, shipname
FROM Sales.Orders
)
INSERT @TestTable
SELECT rownumber, orderid, shipname
from C RETURN
END

好了我们过了一遍关于UDF创建的几种方式,我们回到主题,我们创建一个如下UDF

USE TSQL2012
GO IF OBJECT_ID('dbo.GetId') IS NOT NULL
DROP FUNCTION dbo.GetId;
GO CREATE FUNCTION dbo.GetId
(@id INT) RETURNS TABLE WITH SCHEMABINDING
AS
RETURN
SELECT val1 FROM compare.t_inner WHERE id = @id
GO

此时我们在对应数据库中的表值函数文件夹下能看到我们创建的函数

因为上述我们是查询表compare.t_inner中的值,此时我们删除该表看看。

此时我们会发现该表无法删除出现上述错误。因为我们上述创建的UDF依赖于compare.t_inner表,所以现在无法删除该表,该表引用了自定义函数GetId。下面我们修改上述我们在UDF中查询的列val1为val3看看

在VIEW中的使用

USE TSQL2012
GO IF OBJECT_ID('dbo.GetId') IS NOT NULL
DROP FUNCTION dbo.GetId;
GO CREATE VIEW GetId WITH SCHEMABINDING
AS
SELECT val1 FROM compare.t_inner

此时删除表compare.t_inner依然会出现和UDF中的错误。在使用SCHEMABINDING约束时不能进行*操作,会出现如下图错误:

USE TSQL2012
GO IF OBJECT_ID('dbo.GetId') IS NOT NULL
DROP FUNCTION dbo.GetId;
GO CREATE VIEW GetId WITH SCHEMABINDING
AS
SELECT * FROM compare.t_inner

下面再看其他情况利用视图到跨数据库进行查询,我们创建两个数据库并分别在对应数据库创建一个测试表。

CREATE DATABASE TEST1
CREATE DATABASE TEST2
GO
-- Table1
USE Test1
GO
CREATE TABLE TABLE1 (ID INT)
GO
USE Test2
GO
-- Table2
CREATE TABLE TABLE2 (ID INT)
GO
USE Test1
GO

接下来通过执行SCHEMABINDING来创建视图

CREATE VIEW CrossDBView
WITH SCHEMABINDING
AS
SELECT t1.ID AS t1id, t2.ID AS t2id
FROM Test1.dbo.Table1 t1
INNER JOIN Test2.dbo.Table2 t2 ON t1.ID = t2.ID
GO

上述指定SCHEMABINDING出现错误也就是说在跨数据库查询时会出现错误,对于引用对象仅限于两部分名称。到这里我们为在视图和UDF中使用SCHEMABINDING作出如下结论:

(1)在视图和UDF中使用SCHEMABINDING时必须满足两个要求,第一个是不允许在SELECT子句中使用*,第二个则是当引用对象时必须使用架构限定的两部分名称。

(2)在视图上创建索引时必须指定SCHEMABINDING。

如上讲了这么多关于SCHEMABINDING使用的限制,可以算是缺点吧,难道就没优点了么,如果没优点我们也不会讲了,当然也没必要给出SCHEMABINDING的使用了。当指定SCHEMABINDING时能提高UDF和视图的查询性能,当对象指定架构对象时,在查询计划中不会产生不必要的Spoll操作。我们看如下例子:

CREATE FUNCTION dbo.ComputeNum(@i int)
RETURNS int
BEGIN
RETURN @i * +
END

上述我们没有提供SCHEMABINDING选项,此时UDF不会访问任何数据库对象,当一个函数和视图没有SCHEMABINDING选项时就无法确保底层的数据库对象是什么,所以此时会去访问每个正在执行的UDF,为了避免这种性能问题,我们通过指定SCHEMABINDING是安全的并且不会去遍历访问每一个正在运行的UDF。所以在视图和UDF中一般建议指定SCHEMABINDING选项。

总结

本节我们讨论了在UDF和视图中指定SCHEMABINDING的问题,其实对视图查询还是有诸多限制,大部分情况下利用常规查询和存储过程来实现更加灵活。我们下节看看APPLY运算符的使用,简短的内容,深入的理解,我们下节再会。

SQL Server-聚焦在视图和UDF中使用SCHEMABINDING(二十六)的更多相关文章

  1. 使用SQL Server 2000索引视图提高性能

    什么是索引视图? 许多年来,Microsoft? SQL Server? 一直都提供创建虚拟表(称为视图)的功能.在过去,这些视图主要有两种用途: 提供安全机制,将用户限制在一个或多个基表中的数据的某 ...

  2. SQL Server 2008 错误15023:当前数据库中已存在用户或角色

    解决SQL Server 2008 错误15023:当前数据库中已存在用户或角色,SQLServer2008,错误15023,在使用SQL Server 2008时,我们经常会遇到一个情况:需要把一台 ...

  3. SQL SERVER将某一列字段中的某个值替换为其他的值 分类: MSSQL 2014-11-05 13:11 67人阅读 评论(0) 收藏

    SQL SERVER将某一列字段中的某个值替换为其他的值 UPDATE 表名 SET 列名 = REPLACE(列名 ,'贷','袋') SQL SERVER"函数 replace 的参数 ...

  4. 报错:此版本的SQL Server Data Tools与此计算机中安装的数据库运行时组件不兼容

    在Visual Studio 2012中使用Entity Framework,根据模型生成数据库时,报如下错误: 无法在自定义编辑器中打开Transact-SQL文件此版本的SQL Server Da ...

  5. SQL Server事务、视图和索引

    废话不多说,直接上干货 14:13:23 事务 概括:事务是一种机制,一个操作序列,包含一组数据库操作命令,并且把所有的命令作为一个整体一起 向系统提交或撤销操作 请求. 事务的特性:   1.原子性 ...

  6. SQL Server 索引和视图

    Ø 索引 1. 什么是索引 索引就是数据表中数据和相应的存储位置的列表,利用索引可以提高在表或视图中的查找数据的速度. 2. 索引分类 数据库中索引主要分为两类:聚集索引和非聚集索引.SQL Serv ...

  7. SQL Server 动态管理视图(DMVs)

    DMV在本地部署的SQL Server中需要VIEW SERVER STATE的权限   和事务有关的DMV sys.dm_tran_active_transactions:返回与您的当前逻辑数据库的 ...

  8. SQL Server 索引和视图【转】

    Ø 索引 1. 什么是索引 索引就是数据表中数据和相应的存储位置的列表,利用索引可以提高在表或视图中的查找数据的速度. 2. 索引分类 数据库中索引主要分为两类:聚集索引和非聚集索引.SQL Serv ...

  9. SQL server 触发器、视图

    一.触发器 1.触发器为特殊类型的存储过程,可在执行语言事件时自动生效.SQL Server 包括三种常规类型的触发器:DML 触发器.DDL 触发器和登录触发器. 主要讲述DML触发器,DML触发器 ...

随机推荐

  1. ASP.NET Core MVC/WebAPi 模型绑定探索

    前言 相信一直关注我的园友都知道,我写的博文都没有特别枯燥理论性的东西,主要是当每开启一门新的技术之旅时,刚开始就直接去看底层实现原理,第一会感觉索然无味,第二也不明白到底为何要这样做,所以只有当你用 ...

  2. HTML 事件(一) 事件的介绍

    本篇主要介绍HTML中的事件知识:事件相关术语.DOM事件规范.事件对象. 其他事件文章 1. HTML 事件(一) 事件的介绍 2. HTML 事件(二) 事件的注册与注销 3. HTML 事件(三 ...

  3. 利用bootstrap的carousel.js实现轮播图动画

    前期准备: 1.jquery.js. 2.bootstrap的carousel.js. 3.bootstrap.css. 如果大家不知道在哪下载,可以联系小颖,小颖把这些js和css可以发送给你. 一 ...

  4. jQuery学习之路(6)- 简单的表格应用

    ▓▓▓▓▓▓ 大致介绍 在CSS技术之前,网页的布局基本都是依靠表格制作,当有了CSS之后,表格就被很多设计师所抛弃,但是表格也有他的用武之地,比如数据列表,下面以表格中常见的几个应用来加深对jQue ...

  5. javascript匹配各种括号书写是否正确

    今天在codewars上做了一道题,如下 看上去就是验证三种括号各种嵌套是否正确书写,本来一头雾水,一种括号很容易判断, 但是三种怎么判断! 本人只是个前端菜鸟,,不会什么高深的正则之类的. 于是,在 ...

  6. java 利用ManagementFactory获取jvm,os的一些信息--转

    原文地址:http://blog.csdn.net/dream_broken/article/details/49759043 想了解下某个Java项目的运行时jvm的情况,可以使用一些监控工具,比如 ...

  7. git-2.10.2-64-bit介绍&&git下载&&git安装教程

    Git介绍 分布式:Git系统是一个分布式的系统,是用来保存工程源代码历史状态的命令行工具. 保存点:Git的保存点可以追踪源码中的文件, 并能得到某一个时间点上的整个工程项目的状态:可以在该保存点将 ...

  8. bzoj3095--数学题

    题目大意:给定一个长度为n的整数序列x[i],确定一个二元组(b, k)使得S=Σ(k*i+b- x[i])^2(i∈[0,n-1])最小 看Claris大神的题解就行了.实际上就是用2次二次函数的性 ...

  9. arcgis api for js入门开发系列六地图分屏对比(含源代码)

    上一篇实现了demo的地图标绘模块,本篇新增地图地图分屏对比模块,截图如下(源代码见文章底部): 对效果图的简单介绍一下,在demo只采用了两分屏对比,感兴趣的话,可以在两分屏的基础上拓展,修改css ...

  10. 2DToolkit官方文档中文版打地鼠教程(二):设置摄像机

    这是2DToolkit官方文档中 Whack a Mole 打地鼠教程的译文,为了减少文中过多重复操作的翻译,以及一些无必要的句子,这里我假设你有Unity的基础知识(例如了解如何新建Sprite等) ...