如何在 Oracle 数据库中创建临时表?

Posted

技术标签:

【中文标题】如何在 Oracle 数据库中创建临时表?【英文标题】:How do you create a temporary table in an Oracle database? 【发布时间】:2011-02-09 22:05:50 【问题描述】:

我想在 Oracle 数据库中创建一个临时表

类似

Declare table @table (int id)

在 SQL 服务器中

然后用 select 语句填充它

有可能吗?

谢谢

【问题讨论】:

【参考方案1】:

是的,Oracle 有临时表。这是一个链接,指向描述它们的 AskTom 文章,here 是官方的 oracle CREATE TABLE 文档。

但是,在Oracle 中,只有临时表中的数据 是临时的。该表是其他会话可见的常规对象。在 Oracle 中频繁创建和删除临时表是一种不好的做法。

CREATE GLOBAL TEMPORARY TABLE today_sales(order_id NUMBER)
ON COMMIT PRESERVE ROWS;

Oracle 18c 添加了私有临时表,它们是单会话内存对象。有关详细信息,请参阅the documentation。私有临时表可以动态创建和删除。

CREATE PRIVATE TEMPORARY TABLE ora$ptt_today_sales AS
SELECT * FROM orders WHERE order_date = SYSDATE;

临时表可能很有用,但它们在 Oracle 中经常被滥用。通常可以通过使用内联视图将多个步骤组合到一个 SQL 语句中来避免它们。

【讨论】:

没有反对意见,但我绝不会为全局临时表推荐 CREATE TABLE AS SELECT - 经验不足的开发人员可能会错误地认为他们必须每次都以这种方式填充 GTT。当然,这是从另一个表中复制定义的便捷方式,但这个示例可能会让一些人感到困惑。 我完全同意 Jeffrey Kemp 的观点,这只是创建此表的一种方式,我遇到了这个问题,然后意识到,我是否必须将此 select 语句放在我的 DDL 中。 你可以添加"where 1=0"; @Palcente 仍然暗示您需要一个具有相同结构的“真实表”才能创建一个临时表,但事实并非如此(另见this answer。除此之外,这个答案没有指出不仅仅是 GLOBAL 临时表,还可以使用“普通”临时表。与 SQL Server 的区别,如pointed out by Matthew,另一个重要的一点是人们应该确保不要错过(或者想知道关于已经存在的对象的“第二次调用”错误;) CREATE TABLE AS SELECT 的有效用例:从具有 LOB 列的远程表中选择,因为您不能直接从它们中选择 SELECT。我正在编写一个从远程数据库复制记录的过程,这是我的解决方案:将记录放入 GTT,然后从该记录复制到“真实”表。【参考方案2】:

提示.. Oracle 中的临时表与 SQL Server 不同。您创建它一次且仅一次,而不是每个会话。您插入其中的行仅对您的会话可见,并在您结束会话(或事务结束,具体取决于您使用哪个“ON COMMIT”子句)时自动删除(即TRUNCATE,而不是DROP)使用)。

【讨论】:

我不太明白。你说你只创建一次,而不是每次会话。但是,您还说每个会话都会删除临时表。这是否意味着您需要在每个会话中创建临时表? DELETED,不是DROPped。 您不会在每个会话中创建临时表,而是一次。该表在整个系统中可用。可以从您创建的任何会话(包括并行会话)访问该表。但是当您从一个会话中插入数据时,该数据在系统中的其他并行会话中不可见。一个会话的数据仅是该会话的属性。因此,数据是特定于会话的,而不是系统可见的。因此,当您关闭一个会话时,该会话的数据将从表中删除。【参考方案3】:
CREATE GLOBAL TEMPORARY TABLE Table_name
    (startdate DATE,
     enddate DATE,
     class CHAR(20))
  ON COMMIT DELETE ROWS;

【讨论】:

请注意,行将始终在会话结束时被删除; ON COMMIT DELETE ROWS 表示如果您在会话期间逐步提交,它们将很快被丢弃。 zygimantus,是的,您可以在会话期间手动删除。在会话期间,临时表的行为与普通表完全相同。从用户的角度来看,临时表和真实表之间的唯一区别是,一旦会话结束,所有行都会被删除,并且没有其他会话可以读取会话使用的表的内容。每个会话都有一个表实例;两个会话可以同时使用同一个临时表,并且有两组不同的行,没有任何冲突。【参考方案4】:
CREATE TABLE table_temp_list_objects AS
SELECT o.owner, o.object_name FROM sys.all_objects o WHERE o.object_type ='TABLE';

【讨论】:

请格式化您的答案。如果你写一些关于你的代码的东西会很好。

以上是关于如何在 Oracle 数据库中创建临时表?的主要内容,如果未能解决你的问题,请参考以下文章

oracle 怎么在存储过程中创建一个临时表,在里面插入数据,再查找这个临时表的所有数据,最后drop这个表。

在 FUNCTION 中创建临时表 [重复]

mysql数据库怎么把查询出来的数据生成临时表

Oracle中如何在储过程中使用临时表

Oracle 中临时表的替代方案

如何在 SQL 中创建临时表以用于多个 ADF 活动?