Oracle、SqlServer——临时表

摘要:
当然,会话类型临时表可以在会话期间使用delete临时表名称;清除临时表数据。

一、oracle

1、概述

oracle数据库的临时表的特点:

  • 临时表默认保存在TEMP中;
  • 表结构一直存在,直到删除;即创建一次,永久使用;
  • 不支持主外键。
  • 可以索引临时表和在临时表基础上建立视图。建立在临时表上的索引也是临时的,也是只对当前会话或者事务有效. 临时表可以拥有触发器.

临时表分为事务型和会话型

  • 会话型:基于会话的临时表,数据从会话开始到会话结束之间是有效的,当会话结束时,表中的数据会自动清空。不同会话之间的数据是隔离的,互不影响。
  • 事务型:基于事务的临时表,其比会话型的临时表更灵活,可以认为是从会话型临时表的优化,因为表中的数据的保存时间与会话型相同,有效期从会话开始,在会话结束时,数据库自动清空临时表中的数据。与会话型临时表不同的是 事务提交或者事务回滚 时将清空临时表中的数据。当然,会话型临时表在会话期间可以采用 delete 临时表名;的方式清空临时表数据。

语法:

create global temporary table 临时表名
(
……
)
on commit [preserve|delete] rows; 

  • preserve时就是会话(SESSION)型的临时表
  • delete就是事务(TRANSACTION)型的临时表 

2、示例:

(1)、创建临时表

declare tempisexist integer:=0;
begin
  select count(*) into tempisexist from all_tables where table_name='NK_SLTJ';
  if tempisexist=0 then--不存在临时表就创建一个
    execute immediate('
      CREATE GLOBAL TEMPORARY TABLE NK_SLTJ
      (
        LCK_FJNM varchar(36),
        LCMC varchar(70),
        GFX integer,
        ZFX integer,
        DFX integer,
        KZDSL integer
      )
      on commit preserve rows'  --preserve表示回话级。
    );
  end if;
end;

(2)、使用临时表

  declare
    FXZ NUMBER;
    FJNM varchar(36);
    ZZNM varchar(36):='77c48880-a2be-4d3c-97b7-26f8de0bee63';
    CURSOR NKFXZcur is select NKFXJZ_FXZ,NKLCK_FJNM from NKFXJZ INNER JOIN NKLCK ON NKLCK_NM=NKFXJZ_LCNM where NKLCK_ZZNM=ZZNM;
  begin
    delete NK_SLTJ; --防止在统一会话中多次执行导致数据重复,因此程序一开始就应清空临时表数据 
    insert into NK_SLTJ SELECT NKLCK_FJNM, NKLCK_MC,0,0,0,KZD FROM  --向临时表插入数据。
      ( select KZDSL.NKLCK_FJNM,KZDSL.KZD,LCJZ.NKLCK_MC from
      (select substr(NKLCK_FJNM,1,4) as NKLCK_FJNM, count(NKNKJZ_KZD) AS KZD from NKLCK LEFT join NKNKJZ ON NKNKJZ_LCNM =NKLCK_NM WHERE NKLCK_ZZNM=ZZNM group by substr(NKLCK_FJNM,1,4)) KZDSL
    INNER JOIN
      (select NKLCK_FJNM, NKLCK_MC from NKLCK WHERE NKLCK_JC=1 and NKLCK_ZZNM=ZZNM) LCJZ ON LCJZ.NKLCK_FJNM=KZDSL.NKLCK_FJNM) ccc;

    open NKFXZcur; --打开游标
    fetch NKFXZcur INTO FXZ,FJNM; --提取游标数据
    while NKFXZcur%FOUND loop --循环
      if FXZ>=3.5 and FXZ<=5 then --高风险
        update NK_SLTJ set GFX=GFX+1 where LCK_FJNM=substr(FJNM,0,4);
      elsif FXZ>2 and FXZ<3.5 then --中风险
        update NK_SLTJ set ZFX=ZFX+1 where LCK_FJNM=substr(FJNM,0,4);
      else
        if FXZ>=0 and FXZ<=2 then --低风险
          update NK_SLTJ set DFX=DFX+1 where LCK_FJNM=substr(FJNM,0,4);
        end if;
      end if;
      fetch NKFXZcur INTO FXZ,FJNM ;
    end loop;--结束循环
  close NKFXZcur; --关闭游标
end;

3、oracle创建全局表

  1. 以常规表的形式创建临时数据表的表结构,但要在每一个表的主键中加入一个 SessionID 列以区分不同的会话。(可以有 lob 列和主外键)
  2. 写一个用户注销触发器,在用户结束会话的时候删除本次会话所插入的所有记录 (SessionID 等于本次会话 ID 的记录 ) 。
  3. 程序写入数据时,要顺便将当前的会话 ID(SessionID) 写入表中。
  4. 程序读取数据时,只读取与当前会话 ID 相同的记录即可。

功能增强的扩展设计:

    1. 可以在数据表上建立一个视图,视图对记录的筛选条件就是当前会话的SessionID 。
    2. 数据表中的SessionID 列可以通过Trigger 实现,以实现对应用层的透明性。
    3. 高级用户可以访问全局数据,以实现更加复杂的功能。

二、SqlServer

1、临时表概述

SqlServer临时表有两种:局部临时表、全局临时表。

(1)临时表的共同特点:

  • 无论会话的数据库上下文如何,临时表都被保存到 tempdb 数据库中;
  • 当临时表数据较少时,页被保存到内存中;内存不足时,才持久化临时表的页;
  • 判断临时表是否存在:if object_id('tempdb..#临时表名','U') N) is not null print '存在';

(2)临时表之间的区别

局部临时表:

  临时表名前以#开头,临时表由创建该表的会话所有,为实现不同会话之间同名的临时表相互隔离,SqlServer为表名称添加下划线和唯一的数字后缀以区分不同会话间同名的临时表。即不同会话之间创建的临时表表名虽然我们看到的是一样,但实际上不一样。临时表的可见性与C#、C语言的变量类似,只对调用堆栈中的创建级别和创建级别的内部级别可见,如在存储过程中创建临时表,在存储过程结束后,临时表即被自动销毁。如果临时表在会话的最外层创建临时表,则在会话、批处理和内部级别中的任何地方都有效,直到会话终止时才销毁。 有效期为到创建级别范围内。同一个会话内可以在不同的级别内创建相同名称的局部临时表,但容易在表名解析时导致错误。

全局临时表:

  表名以##开头,可以被所有的会话访问,且任何会话均可以删除全局临时表。全局临时表适用于在多个会话之间共享临时数据而不用担心安全问题,全局临时表的有效期为会话期间而不是创建级别,在创建全局临时表的会话结束后,全局临时表不再向新的会话发放锁,而等现有的会话访问完释放完锁后将销毁全局临时表。

 2、创建不属于任何会话的全局临时表

该全局临时表由SqlServer维护一个大于0的引用计数器以确保不会被数据库自动删除。

方法:

在master数据库中创建有 sp_前缀、使用 startup 选项标记的特殊存储过程,

例:

use master;
go
if object_id('dbo.sp_test') is not null
  drop proc dbo.sp_test
go
create proc dbo.sp_test
as 
  create table ##test
  (
    name varchar(36)
  );
go
exec dbo.sp_procoption 'sp_test','startup','true';

这样一来,这种临时表的作用就和永久表没有多大区别了。

三、oracle与SqlServer 临时表的区别

oracle:

  • 有事务表和会话表两种;
  • 临时表永远保留表结构,数据保存在磁盘上。与永久表唯一不同的是在用户会话结束或者事务提交、回滚后删除数据,但是保留表结构;

SqlServer则是本地和全局临时表。

  • SqlServer:在需要临时表时手动创建,会话结束时直接删除表结构。
  • 当临时表数据较少时,页被保存到内存中;内存不足时,才持久化临时表的页;

 

免责声明:文章转载自《Oracle、SqlServer——临时表》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇PageHelper分页插件Android 数据存储04之Content Provider下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Java事务

Java事务的类型有三种:JDBC事务、JTA(Java Transaction API)事务、容器事务。常见的容器事务如Spring事务,容器事务主要是J2EE应用服务器提供的,容器事务大多是基于JTA完成,这是一个基于JNDI的,相当复杂的API实现。所以本文暂不讨论容器事务。本文主要介绍J2EE开发中两个比较基本的事务:JDBC事务和JTA事务。 J...

MySql 事务实现机制 几种日志undo log、 binlog、redo log

你知道MySQL的原子性是怎么保证的吗? 谁都知道在事务里边原子性的意思:”一个事务包含多个操作,这些操作要么全部执行,要么全都不执行“ 事务保证需要用到一下几个常见 log undo log binlog redo log 一、什么是binlog   binlog其实在日常的开发中是听得很多的,因为很多时候数据的更新就依赖着binlog。   举个很...

MySQL存储过程之事务管理

  MySQL存储过程之事务管理 ACID:Atomic、Consistent、Isolated、Durable 存储程序提供了一个绝佳的机制来定义、封装和管理事务。 1,MySQL的事务支持 MySQL的事务支持不是绑定在MySQL服务器本身,而是与存储引擎相关: Java代码 1         MyISAM:不支持事务,用于只读程序提高性能 ...

ActiveMQ之JMS及保证消息的可靠性&amp;lt;持久化、事务、签收&amp;gt;(三)

1.JAVAEE 是一套使用Java 进行企业级开发的13 个核心规范工业标准 , 包括:  JDBC  数据库连接  JNDI  Java的命名和目录接口  EJB   Enterprise java bean  RMI   远程方法调用    一般使用TCP/IP 协议  Java IDL    接口定义语言  JSP      Servlet   X...

django之数据库表的单表查询

一、添加表记录 对于单表有两种方式 # 添加数据的两种方式 # 方式一:实例化对象就是一条表记录 Frank_obj = models.Student(name ="海东",course="python",birth="2000-9-9",fenshu=80) Frank_obj.save() # 方式二: mo...

KUDU 介绍

前言 近两年,KUDU 在大数据平台的应用越来越广泛。在阿里、小米、网易等公司的大数据架构中,KUDU 都有着不可替代的地位。本文通过分析 KUDU 的设计, 试图解释为什么 KUDU 会被广泛应用于大数据领域,因为还没有研究过 KUDU 的代码,下面的介绍是根据 KUDU 的论文和网上的一些资料学习自己理解所得,如有不实之处,劳请指正。 背景 在 KU...