博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SQL Server 中的临时表解析
阅读量:7230 次
发布时间:2019-06-29

本文共 2237 字,大约阅读时间需要 7 分钟。

有时需要把数据临时保存到表中, 而且在某些情况下, 可能并不想使用永久性的表。例如,假设需要让数据只对当前会话可见,或者只对当前批处理可见。 另一个场景是, 假设想让数据对所有用户都可见, 允许他们看到完整的DDL和进行所有DML访问, 但却没有在任何用户数据库中创建表的权限。在这种情况下, 使用临时表可能会更方便。 SQL Server支持三种类型的临时表: 局部临 时表、 全局临时表及表变量。不论会话的数据库上下文如何,临时表都被创建在tempdb中。

一.局部临时表

要创建局部临时表,只需要在命名时以单个数字符号(#)作为前缀,例如#T1。

局部临时表只对创建它的会话在创建级和调用堆栈内部级(内部的过程、函数、触发器、 以及动态批处理)是可见的。当创建级例程弹出调用堆栈,SQL Server就会自动删除相应的临时表。例如,假设一个存储过程Procl调用了另一个存储过程Proc2,而Proc2又调用了另一个存储过程Proc3,Proc3又调用了存储过程Proc4。Proc2在调用Proc3之前 创建了一个临时表#Tl。这时表#T1对Proc2、Proc3、以及Proc4是可见的,而对Procl1是不可见的,当Proc2完成时,SQL Server就会自动删除这个临时表。如果临时表是在 会话最外层嵌套的一个特殊的批处理(@@NESTLEVEL函数的返回值是O)中创建的, 则这个表对所有随后的批处理也是可见的,只有当创建会话从SQL Server实例断开时, SQL Server才会自动删除它。

可能会疑惑,当两个会话创建的局部临时表具有相同的名称时,SQL Server怎么避免名 称冲突。SQL Server内部会为临时表名称增加一个后缀,使表名称在tempdb数据库中保持惟一。

 

二.局部临时表

如果创建的是全局临时表则它对其他所有会话都可见。当创建临时表的会话断开数据库的联接,而且也没有活动在引用全局临时表时,SQL Server会自动删除相应的全局临时表。要创建全局临时表,只需要在命名时用两个数字符号(##)作为前缀,如##T1。

当需要和所有人共享临时数据时,就可以用全局临时表。访问全局临时表不需要任何特殊的权限,所有人都可以获取完整的DDL和DML访问。当然,每个人都可以完全访问也意味着任何人都可以删除这个表,所以也应该谨慎考虑全局临时表的副作用。例如,以下代码创建了一个全局临时表##Globals,它包含id和val两个列:

CREATE TABLE dbo. ##Globals(    id sysname NOT NULL PRIMARY KEY,    val SQL_VARIANT NOT NULL)

这个表在这里是想模仿全局变量(SQL Server不支持全局变量)。列id的数据类型是 sysname (SQL Server在内部用这个类型来代表标识符),列val的数据类型是SQL_VARIANT (一种通用的类型,差不多可以保存任何基础类型的值)。

 

三.表变量

表变量和局部临时表在某些方面有相同之处,也有不同之处。声明表变量的方式和声明其他变量类似,使用的都是DECLARE语句。

和使用局部临时表一样,表变量在tempdb数据库中也有对应的表作为其物理表示,而不是像通常所理解的那样,以为表变量只在内存中存在。和局部临时表类似,表变量也只对创建它的会话可见,但允许访问的范围更有限,它只对当前批处理可见。表变矗对调用堆栈中当前批处理的内部批处理是不可见的,对会话中随后的批处理也是不可见的。

如果回滚一个显式事务,在事务中对临时表所做的更改也将回滚;不过,通过语句对表量进行的更改, 如果在事务中已经完成了, 则不会被回滚。 只有通过活动语句进行的更改, 而且操作失败或在完成之前被终止了, 这样的更改才会被撤消。

临时表和表变量在性能优化方面也有区别,从性能上考虑, 对于少量的数据(只有几行),使用表变量更有意义, 否则,应该使用临时表。

 

四.表类型

SQL Server 2008引入了对表类型的支持。 通过创建表类型, 可以把表的定义保存到数据库中, 以后在定义表变量 、存储过程和用户定义函数的输入参数时,可以将表类型作为表的定义而重用。以下代码在数据库中创建了一个表类型 dbo.OrderTotalsByYear:

IF TYPE_ID('dbo.OrderTotalsByYear') IS NOT NULL     DROP TYPE dbo.OrderTotalsByYear;CREATE TYPE dbo.OrderTotalsByYear AS TABLE(        orderyear INT NOT NULL PRIMARY KEY,     qty INT NOT NULL )

创建好表类型以后, 每当需要根据表类型的定义来声明表变量时, 就不需要重复表定义代码, 只要简单的将变量的类型指定为dbo.OrderTotalsByYear就可以, 如下所示:

DECLARE @MyorderTotalssyvear AS dbo.OrderTotalsByYear;

 

 

好了,本篇文章就介绍到这儿,欢迎大家留言交流;喜欢或有帮助到您的话,点个赞或推荐支持一下!

 

转载于:https://www.cnblogs.com/johnvwan/p/9497983.html

你可能感兴趣的文章
提高javascript编码质量-68-1
查看>>
设计模式开篇 - 简单工厂模式
查看>>
Spring MVC 注解和XML的区别
查看>>
利用Swoole实现PHP+websocket直播,即使通讯代码,及linux下swoole安装基本配置
查看>>
Elastic学习第一天遇到的问题以及添加的一些操作
查看>>
Python lambda介绍
查看>>
BSON与JSON的区别
查看>>
文件系统存储数据,与数据库系统存储数据的差别
查看>>
linux之awk
查看>>
第九章 接口
查看>>
XCode4.2.1 使用NavigationController实现View切换
查看>>
如何让NSURLConnection在子线程中运行
查看>>
es6-Generator
查看>>
Python3.6单例模式报错TypeError: object() takes no parameters的解决方法
查看>>
HTML常用标记(选择性,不全)
查看>>
用一辈子去领悟的22条生活真谛
查看>>
1968: [Ahoi2005]COMMON 约数研究
查看>>
discuz 启用html code 显示问题
查看>>
A1027. Colors in Mars (20)
查看>>
[SRM568]DisjointSemicircles
查看>>