sql server中的临时表、表变量和公用表表达式
在编写T-SQL语句的时候,SQL Server提供了三种方法临时存储某些结果集,分别是临时表、表变量和公用表表达式。
临时表
临时表需要在临时数据库TempDB中通过I/O操作来创建表结构,一旦用户退出SQL Server环境,临时表会自动被删除。临时表有两种,一种是本地临时表,仅在当前会话中可见,前缀是【#】;一种是全局临时表,在所有会话中都可见,前缀是【##】。
临时表的优缺点
临时表的优点是能够和普通的物理表一样长久存储数据,可以建立索引,能存储大量的数据。
临时表的缺点是使用不方便,在使用之后还要手动通过DROP语句去删除,否则会一直存在,直到此次数据库连接关闭。
本地临时表与本地临时表的特点
1.本地临时表就是用户在创建表的时候添加了【#】前缀的表,其特点是根据数据库连接独立。只有创建本地临时表的数据库连接有表的访问权限,其它连接不能访问该表。
2.不同的数据库连接中,创建的本地临时表虽然名字相同,但是这些表之间相互并不存在任何关系;在SQL Server中,通过特别的命名机制保证本地临时表在数据库连接上的独立性。
3.真正的临时表利用了数据库临时表空间,由数据库系统自动进行维护,因此节省了表空间。并且由于临时表空间一般利用虚拟内存(其实还是硬盘),大大减少了硬盘的I/O次数,因此也提高了系统效率。
4.临时表在事务完毕或会话完毕数据自动清空,不必记得用完后删除数据。
-- 创建临时表方法一,SELECT INTO ... FROM ...
SELECT INTO #TEMP_USERS FROM USERS; -- 创建临时表方法二,CREATE TABLE ...
CREATE TABLE #TEMP_USERS(ID VARCHAR, NAME VARCHAR);
INSERT INTO #TEMP_USERS SELECT ID, NAME FROM USERS; -- 使用临时表
SELECT * FROM #TEMP_USERS; -- 删除临时表(建议是使用完立即删除)
DROP TABLE #TEMP_USERS;
全局临时表与全局临时表的特点
全局临时表的名称以两个数字符号 【##】 打头,创建后对任何数据库连接都是可见的,当所有引用该表的数据库连接从SQL Server断开时被删除。
-- 创建临时表方法一,SELECT INTO ... FROM ...
SELECT INTO ##TEMP_USERS FROM USERS; -- 创建临时表方法二,CREATE TABLE ...
CREATE TABLE ##TEMP_USERS(ID VARCHAR, NAME VARCHAR);
INSERT INTO ##TEMP_USERS SELECT ID, NAME FROM USERS; -- 使用临时表
SELECT * FROM ##TEMP_USERS; -- 删除临时表(建议是使用完立即删除)
DROP TABLE ##TEMP_USERS;
表变量
表变量在内存/TempDB中以表结构的形式存在,其定义与普通的变量一致,使用上和普通表类似,可以不需要产生磁盘I/O。
表变量的优点
1.与其他变量的定义一样,表变量具有良好的定义范围,并会被自动清除。
2.在存储过程中使用表变量会减少存储过程重新编译的发生。
3.表变量需要更少的锁请求和日志资源。
4.可以在表变量上使用UDF、UDDT和XML。
表变量的缺点
1.在表变量上没有统计信息,查询优化器根据固定的预估值来选择执行计划,在数据很多的情况下,会导致查询优化器选择很差的执行计划。
2.不能直接在表变量上创建索引,但可以通过创建约束(主键、唯一)来建立索引。
3.在DECLARE后,不能再对表变量进行更改。
4.不能对表变量执行INSERT EXEC或SELECT INTO语句。
5.不能通过EXEC或SP_EXECUTESQL来执行牵涉到表变量的动态SQL语句,但如果表变量是在动态SQL语句内定义的,则可以。
表变量的使用
如果表的行数非常多,使用表变量会十分浪费资源。一般建议是对于行数较少的情况下(小于1000行)可以使用表变量;如果行数很多(有几万行)可以使用临时表。
-- 定义表变量
DECLARE @TEMP_USERS TABLE(ID VARCHAR, NAME VARCHAR);
-- 往表变量中插入数据
INSERT INTO @TEMP_USERS SELECT ID, NAME FROM USERS;
-- 使用表变量
SELECT * FROM @temp;
要注意的是,表变量的有效范围是整个批处理、程序或函数的处理过程。当在一段程序中发出GO命令的时候,表变量就会被删除,不再有效了。
公用表表达式
公用表表达式(CTE,Common Table Expression)的定义是在内存中保存的临时存储结果集对象,不会产生磁盘I/O,也不需要按照表变量那样定义,使用的方法则和普通表类似。
公用表表达式的注意事项
1.WITH AS-做子查询部分(subquery factoring)。
2.如果WITH AS所以定的表名被调用两次以上,则优化器会自动将WITH AS所获取的数据放入临时表里,如果只是被调用一次,则不会。
3.WITH AS可以被紧跟着的一条SQL语句使用多次,但不能被紧跟着的多条SQL语句使用。
4.如果将CTE用在属于批处理的一部分的语句中,那么在它之前的语句必须以分号结尾。
公用表表达式的定义语法
公用表表达式的定义包括三个部分,分别是表达式的名称(expression_Name),列名列表(column_name)和定义CTE结果集的SELECT查询语句(cte_query_definition)。
WITH expression_name [(column_name [,...n] )] AS (
cte_query_definition
)
公用表表达式的优点
根据微软对CTE好处的描述,可以归结为四点:
1.当不需要将结果集作为视图被多个地方引用时,CTE可以使其更加简洁。
2.GROUP BY语句可以直接作用于子查询所得的标量列.
3.可以在一个语句中多次引用公用表表达式(CTE)。
4.可以使用递归。
非递归公用表表达式
WITH TEMP_USERS AS (
SELECT * FROM USERS
)
SELECT * FROM TEMP_USERS;
可以在接下来的一条语句中多次引用。
WITH TEMP_USERS AS (
SELECT * FROM USERS
)
SELECT * FROM TEMP_USERS WHERE NAME LIKE '杨%'
UNION
SELECT * FROM TEMP_USERS WHERE NAME LIKE '%静';
不可以多条语句引用。
WITH TEMP_USERS AS (
SELECT * FROM USERS
)
SELECT * FROM TEMP_USERS;
SELECT * FROM TEMP_USERS; -- 报错,找不到该表
可以一次定义多个CTE,用逗号隔开。
WITH
TEMP_USERS AS (
SELECT * FROM USERS
),
TEMP_ORGS AS (
SELECT * FROM ORGS
)
SELECT * FROM TEMP_USERS AS A
INNER JOIN TEMP_ORGS AS B ON A.ORG_ID = B.ID;
递归公用表表达式
递归CTE定义至少必须包含两个CTE查询定义,一个是定位点成员,一个是递归成员。可以定义多个定位点成员和递归成员,但必须将所有定位点成员查询定义置于第一个递归成员定义之前。所有CTE查询定义都是定位点成员,但它们引用CTE本身时除外。定位点成员必须与以下集合运算符之一结合使用:UNION ALL、UNION、INTERSECT或EXCEPT。 在最后一个定位点成员和第一个递归成员之间,以及组合多个递归成员时,只能使用UNION ALL集合运算符。
WITH TEMP_ORGS(ID, NAME, PID, LEVEL) AS (
-- 基本语句(递归起始点)
SELECT ID, NAME, PID, 0 AS LEVEL
FROM ORGS
WHERE PID IS NULL UNION ALL -- 递归语句
SELECT A.ID, A.NAME, A.PID, B.LEVEL + 1 AS LEVEL
FROM ORGS AS A
INNER JOIN TEMP_ORGS AS B ON A.PID = B.ID -- 递归调用
)
SELECT * FROM TEMP_ORGS
OPTION(MAXRECURSION 2); -- 指定最大递归次数为2
这里的OPTION是可选的,通过指定MAXRECURSION参数可以用来限制递归的最大次数。
"一旦失望攒够了,这一生都不会为你回头。"
sql server中的临时表、表变量和公用表表达式的更多相关文章
- SQL Server中的临时表和表变量
SQL Server中的临时表和表变量 作者:DrillChina出处:blog2008-07-08 10:05 在SQL Server的性能调优中,有一个不可比拟的问题:那就是如何在一段需要长时间的 ...
- SQL Server中的临时表和表变量 Declare @Tablename Table
在SQL Server的性能调优中,有一个不可比面的问题:那就是如何在一段需要长时间的代码或被频繁调用的代码中处理临时数据集?表变量和临时表是两种选择.记得在给一家国内首屈一指的海运公司作SQL Se ...
- 最简单删除SQL Server中所有数据的方法(不用考虑表之间的约束条件,即主表与子表的关系)
其实删除数据库中数据的方法并不复杂,为什么我还要多此一举呢,一是我这里介绍的是删除数据库的所有数据,因为数据之间可能形成相互约束关系,删除操作可能陷入死循环,二是这里使用了微软未正式公开的sp_MSF ...
- SQL server中使用临时表存储数据
将查询出来的数据直接用“INTO #临时表名称”的方式完成临时表的创建及数据的插入 SELECT * INTO #temp_NowStatusFROM Test SELECT * FROM #temp ...
- c#Winform程序调用app.config文件配置数据库连接字符串 SQL Server文章目录 浅谈SQL Server中统计对于查询的影响 有关索引的DMV SQL Server中的执行引擎入门 【译】表变量和临时表的比较 对于表列数据类型选择的一点思考 SQL Server复制入门(一)----复制简介 操作系统中的进程与线程
c#Winform程序调用app.config文件配置数据库连接字符串 你新建winform项目的时候,会有一个app.config的配置文件,写在里面的<connectionStrings n ...
- Sql Server中的标识列(自增长字段)
一.标识列的定义以及特点 SQL Server中的标识列又称标识符列,习惯上又叫自增列.该种列具有以下三种特点: 1.列的数据类型为不带小数的数值类型2.在进行插入(Insert)操作时,该列的值是由 ...
- [转]SQL Server中临时表与表变量的区别
[转]http://blog.csdn.net/skyremember/archive/2009/03/05/3960687.aspx 我们在数据库中使用表的时候,经常会遇到两种使用表的方法,分别就是 ...
- SQL Server中临时表与表变量的区别
我们在数据库中使用表的时候,经常会遇到两种使用表的方法,分别就是使用临时表及表变量.在实际使用的时候,我们如何灵活的在存储过程中运用它们,虽然它们实现的功能基本上是一样的,可如何在一个存储过程中有时候 ...
- sql Server中临时表与数据表的区别
sql server 中临时表与数据表的区别 1.如何判断临时表和数据表已生成 --如何判断临时表是否已创建--- if exists(select * from tempdb..sysobjects ...
随机推荐
- Spring5源码解析1-从启动容器开始
从启动容器开始 最简单的启动spring的代码如下: @Configuration @ComponentScan public class AppConfig { } public class Mai ...
- Redisson实现分布式锁(1)---原理
Redisson实现分布式锁(1)---原理 有关Redisson作为实现分布式锁,总的分3大模块来讲. 1.Redisson实现分布式锁原理 2.Redisson实现分布式锁的源码解析 3.Redi ...
- Web前端基础(8):JavaScript(二)
1. 数据类型转换 1.1 将数值类型转换成字符串类型 1.1.1 隐式转换 在js中,当运算符在运算时,如果两边数据不统一,CPU就无法计算,这时我们编译器会自动将运算符两边的数据做一个数据类型转换 ...
- 教你如何用Python向手机发送通知
------------恢复内容开始------------ 你曾想尝试在服务器端或电脑上向手机发送通知吗? 你曾烦恼过企业邮箱的防骚扰机制吗? 现在,我们可以用一种简单轻松的方法来代替企业邮箱了! ...
- python-execjs(调用js)
一.安装 pip3 install PyExecJS 电脑上要有nodejs环境 二.使用 一.获取js字符串 首先将js保存至于本地文件或者你可以可以直接读到内存,必须让js以字符串的形式展示 注意 ...
- 【win10】通过环境变量来快速打开应用程序
step1:建一个空文件夹,并把文件夹路径复制到剪贴板. step2:依次右键点击“此电脑”.属性.高级系统设置.环境变量,定位到“系统变量”,点击新建. (说明:环境变量分为用户变量和系统变量,用户 ...
- JS基础语法---do-while循环 + 总结while循环和do-while循环
1. 总结:while循环和do-while循环 while循环特点:先判断,后循环,有可能一次循环体都不执行 do-while循环特点:先循环,后判断,至少执行一次循环体 对比体会: 1. ...
- Xcode里面如何添加和配置pch文件??
开发工具/原料: 1.Mac 2.Xcode(我这里目前用的Xcode的最新版本Xcode 7.3) PCH文件的部分发展史: 定义:pch全称为“precompiled header”,也就是预编译 ...
- [转]关于maven pom.xml中dependency type 为pom的应用
原文地址:http://blog.csdn.net/yao123long/article/details/49925659 dependency为什么会有type为pom,默认的值是什么?depend ...
- 文:你可以杀我,但你不能评价(judge)我
原创 豆瓣影评:“现代战争启示录”豆友影评 2006-12-18 20:24:20 本文刊载于<豆瓣影评>豆友“芹泽虾饺菌”的影评 原文标题<剃刀边缘的疯狂> 文/芹泽虾饺菌 ...