zoukankan      html  css  js  c++  java
  • SQL Server[转]SQL Server中临时表与表变量的区别

    http://blog.csdn.net/skyremember/archive/2009/03/05/3960687.aspx

       我们在数据库中使用表的时候,经常会遇到两种使用表的方法,分别就是使用临时表及表变量。在实际使用的时候,我们如何灵活的在存储过程中运用它们,虽然它们实现的功能基本上是一样的,可如何在一个存储过程中有时候去使用临时表而不使用表变量,有时候去使用表变量而不使用临时表呢?
      临时表

      临时表与永久表相似,只是它的创建是在Tempdb中,它只有在一个数据库连接结束后或者由SQL命令DROP掉,才会消失,否则就会一直存在。临时表在创建的时候都会产生SQL Server的系统日志,虽它们在Tempdb中体现,是分配在内存中的,它们也支持物理的磁盘,但用户在指定的磁盘里看不到文件。

      临时表分为本地和全局两种,本地临时表的名称都是以“#”为前缀,只有在本地当前的用户连接中才是可见的,当用户从实例断开连接时被删除。全局临时表的名称都是以“##”为前缀,创建后对任何用户都是可见的,当所有引用该表的用户断开连接时被删除。

      下面我们来看一个创建临时表的例子:  

        CREATE TABLE dbo.#News
      (
          News_id int NOT NULL,
          NewsTitle varchar(100),
          NewsContent varchar(2000),
          NewsDateTime datetime
      )
      临时表可以创建索引,也可以定义统计数据,所以可以用数据定义语言(DDL)的声明来阻止临时表添加的限制,约束,并参照完整性,如主键和外键约束。比如来说,我们现在来为#News表字段NewsDateTime来添加一个默认的GetData()当前日期值,并且为News_id添加一个主键,我们就可以使用下面的语句: 

       ALTER TABLE dbo.#News
      ADD
      CONSTRAINT [DF_NewsDateTime] DEFAULT (GETDATE()) FOR [NewsDateTime],
      PRIMARY KEY CLUSTERED
      (
      [News_id]
      ) ON [PRIMARY]
      GO
      临时表在创建之后可以修改许多已定义的选项,包括:

      1)添加、修改、删除列。例如,列的名称、长度、数据类型、精度、小数位数以及为空性均可进行修改,只是有一些限制而已。

      2)可添加或删除主键和外键约束。

      3)可添加或删除 UNIQUE 和 CHECK 约束及 DEFAULT 定义(对象)。

      4)可使用 IDENTITY 或 ROWGUIDCOL 属性添加或删除标识符列。虽然 ROWGUIDCOL 属性也可添加至现有列或从现有列删除,但是任何时候在表中只能有一列可具有该属性

       5)表及表中所选定的列已注册为全文索引。

      表变量

      表变量创建的语法类似于临时表,区别就在于创建的时候,必须要为之命名。表变量是变量的一种,表变量也分为本地及全局的两种,本地表变量的名称都是以“@”为前缀,只有在本地当前的用户连接中才可以访问。全局表变量的名称都是以“@@”为前缀,一般都是系统的全局变量,像我们常用到的,如 @@Error代表错误的号,@@RowCount代表影响的行数。

      如我们看看创建表变量的语句:

       DECLARE @News Table
      (
          News_id int NOT NULL,
          NewsTitle varchar(100),
          NewsContent varchar(2000),
          NewsDateTime datetime
      )
      比较临时表及表变量都可以通过SQL的选择、插入、更新及删除语句,它们的的不同主要体现在以下这些:

      1)表变量是存储在内存中的,当用户在访问表变量的时候,SQL Server是不产生日志的,而在临时表中是产生日志的;

      2)在表变量中,是不允许有非聚集索引的;

      3)表变量是不允许有DEFAULT默认值,也不允许有约束;

      4)临时表上的统计信息是健全而可靠的,但是表变量上的统计信息是不可靠的;

      5)临时表中是有锁的机制,而表变量中就没有锁的机制。

      我们现在来看一个完整的例子,来看它们的用法的异同:

      利用临时表  

        CREATE TABLE dbo.#News
      (
          News_id int NOT NULL,
          NewsTitle varchar(100),
          NewsContent varchar(2000),
          NewsDateTime datetime
      )
      INSERT INTO dbo.#News (News_id, NewsTitle, NewsContent, NewsDateTime)
          VALUES (1,'BlueGreen', 'Austen', 200801, GETDATE())
      SELECT News_id, NewsTitle, NewsContent, NewsDateTime FROM dbo.#News
      DROP TABLE dbo.[#News]


      利用表变量     

        DECLARE @News table
      (
          News_id int NOT NULL,
          NewsTitle varchar(100),
          NewsContent varchar(2000),
          NewsDateTime datetime
      )
      INSERT INTO @News (News_id, NewsTitle, NewsContent, NewsDateTime)
          VALUES (1,'BlueGreen', 'Austen', 200801, GETDATE())
      SELECT News_id, NewsTitle, NewsContent, NewsDateTime FROM @News


      我们可以看到上面两种情况实现的是一样的效果,第一种利用临时表的时候,临时表一般被创建后,如果在执行的时候,没有通过DROP Table的操作,第二次就不能再被创建,而定义表变量也不需要进行DROP Table的操作,一次执行完成后就会消失。

      其实在选择临时表还是表变量的时候,我们大多数情况下在使用的时候都是可以的,但一般我们需要遵循下面这个情况,选择对应的方式:

      1)使用表变量主要需要考虑的就是应用程序对内存的压力,如果代码的运行实例很多,就要特别注意内存变量对内存的消耗。我们对于较小的数据或者是通过计算出来的推荐使用表变量。如果数据的结果比较大,在代码中用于临时计算,在选取的时候没有什么分组的聚合,就可以考虑使用表变量。

      2)一般对于大的数据结果,或者因为统计出来的数据为了便于更好的优化,我们就推荐使用临时表,同时还可以创建索引,由于临时表是存放在Tempdb中,一般默认分配的空间很少,需要对tempdb进行调优,增大其存储的空间。

    补充:
        1.使事务日志不会记录表变量。因此,它们脱离了事务机制的范围。

       2.任何一个使用临时表的存储过程都不会被预编译,然而使用表变量的存储过程的执行计划可以预先静态的编译。预编译一个脚本的主要好处在于加快了执行的速度。这个好处对于长的存储过程更加显著,因为对它来说重新编译代价太高。

       3.表变量仅存在于那些变量能存在的相同范围内。和临时表相反,它们在内部存储过程和exec(string)语句里是不可见的。它们也不能在insert/exec语句里使用。

  • 相关阅读:
    springcloud 项目源码 微服务 分布式 Activiti6 工作流 vue.js html 跨域 前后分离
    springcloud 项目源码 微服务 分布式 Activiti6 工作流 vue.js html 跨域 前后分离
    OA办公系统 Springboot Activiti6 工作流 集成代码生成器 vue.js 前后分离 跨域
    java企业官网源码 自适应响应式 freemarker 静态引擎 SSM 框架
    java OA办公系统源码 Springboot Activiti工作流 vue.js 前后分离 集成代码生成器
    springcloud 项目源码 微服务 分布式 Activiti6 工作流 vue.js html 跨域 前后分离
    java 视频播放 弹幕技术 视频弹幕 视频截图 springmvc mybatis SSM
    最后阶段总结
    第二阶段学习总结
    第一阶段学习总结
  • 原文地址:https://www.cnblogs.com/soundcode/p/2323305.html
Copyright © 2011-2022 走看看