如何在Oracle中创建临时表作为另一个表的副本?

时间:2014-11-23 20:30:12

标签: sql database oracle oracle-sqldeveloper

我已经尝试过了:

CREATE GLOBAL TEMPORARY TABLE tempTable AS
SELECT * FROM realTable;

但是,tempTable只有realTable的结构,而不是元素本身。

2 个答案:

答案 0 :(得分:12)

  

“但是,tempTable只有realTable的结构,但不是   元素本身。“

使全局临时表临时的原因是数据是暂时的。首先,数据仅在插入它的会话中可见;任何其他会话都会看到一个空表。其次,数据可以持久存在于事务或会话中,具体取决于ON COMMIT子句;默认为ON COMMIT DELETE ROWS。 Find out more

现在的问题是,Oracle中的DDL语句会发出两个提交,一个在提交之前,一个提交之后。所以DDL语句是一个完整的离散事务。因此......

CREATE GLOBAL TEMPORARY TABLE tempTable AS
SELECT * FROM realTable;

...是一个事务,因为它没有指定ON COMMIT子句,所以它将应用默认值DELETE ROWS。所以空表是预期的行为。

解决方案很简单:使用会话级保留指定ON COMMIT语句:

SQL> select count(*) from t23;

  COUNT(*)
----------
        11

SQL> create global temporary table gtt23
  2  as select * from t23
  3  /

Table created.

SQL> select count(*) from gtt23;

  COUNT(*)
----------
         0

SQL> drop table gtt23;

Table dropped.

SQL> create global temporary table gtt23
  2  on commit preserve rows
  3  as select * from t23
  4  /

Table created.

SQL> select count(*) from gtt23;

  COUNT(*)
----------
        11

SQL> 

通常,我认为使用SELECT * FROM创建GLOBAL TEMPORARY TABLE的策略表明对构造的误解。 Oracle中的GTT是永久数据结构;只有记录是临时的。它们不是像T-SQL中的临时表那样的一次性对象。如果这是你想要的那种东西,你可能应该使用PL / SQL集合。 Find out more

答案 1 :(得分:3)

全局临时表可以具有事务级范围或会话级范围。默认情况下具有事务级范围,这意味着事务完成后数据将消失。如果您使用CREATE TABLE AS SELECT创建全局临时表,则会插入数据,但由于CREATE是DDL,因此语句完成后将立即删除数据。

一种选择是使用不返回任何数据的查询创建结构

CREATE GLOBAL TEMPORARY TABLE tempTable AS
  SELECT * 
    FROM realTable
   WHERE 1=0;

然后插入数据

INSERT INTO tempTable
  SELECT *
    FROM realTable;

当然,考虑到在Oracle中使用不常见的全局临时表(特别是与其他数据库相比),我想确定你真的需要从永久表中创建一个临时表。第一名。