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

本文共 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

你可能感兴趣的文章
kernel和iptables补丁创建和安装
查看>>
mongodb 备份和还原
查看>>
LVS基本介绍及NAT模型配置示例
查看>>
关于开源驰骋工作流引擎ccbpm对bpmn2.0的支持
查看>>
关于通过linux crontab+xtrabackup自动化备份mysql数据的说明
查看>>
mysql中Table is read only的解决
查看>>
CentOS7 搭建 zabbix-server 3.0.10
查看>>
Android四大基本组件介绍与生命周期
查看>>
Essential Grid for WPF
查看>>
python实现一个简单的dnspod api
查看>>
我是在工作?学习?混日子?
查看>>
内存管理初级基础--代码
查看>>
关于Android Force Close 出现的原因 以及解决方法
查看>>
linux tar、find命令运维实践
查看>>
查询oracle数据库编码
查看>>
分发系统-expect-批量同步文件、批量执行命令
查看>>
activiti相关配置
查看>>
poj(1458)(最长公共子序列)
查看>>
virtualbox增加硬盘
查看>>
Exchange 2010邮件收发信大小限制
查看>>