我已经尝试过了:
CREATE GLOBAL TEMPORARY TABLE tempTable AS
SELECT * FROM realTable;
但是,tempTable只有realTable的结构,而不是元素本身。
答案 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中使用不常见的全局临时表(特别是与其他数据库相比),我想确定你真的需要从永久表中创建一个临时表。第一名。