4

我熟悉 Sybase / SQL server,我可以在其中创建一个临时文件。像这样的表:

SELECT * 
INTO   #temp
FROM   tab1 , 
       tab2 
WHERE  tab1.key = tab2.fkey

SELECT * 
FROM   #temp 
WHERE  field1 = 'value' 

#temp 仅在此会话期间存在,并且只能由我看到。

我想在 Oracle 中做类似的事情,但我正在阅读“全局临时表”,这听起来不像是一回事。

如何在 Oracle 中执行与在 Sybase 中相同的操作?

谢谢 :)

4

6 回答 6

4

全局临时表是不一样的,定义在会话结束后仍然存在,表(但不是数据)对所有会话都是可见的。

如果您正在编写存储过程,您是否研究过游标?它有点复杂,但使用临时数据集是一种非常有效和干净的方式。

于 2008-10-21T13:35:41.403 回答
4

您的第一种方法应该是作为单个查询执行此操作:

SELECT * 
FROM   
(
SELECT * 
FROM   tab1 , 
       tab2 
WHERE  tab1.key = tab2.fkey
)
WHERE  field1 = 'value';

对于非常复杂的情况或 temp# 非常大的情况,请尝试使用子查询因式分解子句,可选择使用具体化提示:

with #temp as
(
SELECT /*+ materialize */ 
       * 
FROM   tab1 , 
       tab2 
WHERE  tab1.key = tab2.fkey
)
SELECT * 
FROM   temp#
WHERE  field1 = 'value';

如果这没有帮助,请转到全局临时表方法。

于 2008-10-22T13:31:06.733 回答
2

Oracle 不提供此工具的直接类似物。全局临时表是类似的,但它必须提前创建,并且由于锁定问题可能难以更改。

这种性质的大多数需求都可以通过游标或不同的 pl/sql 集合类型(嵌套表、可变数组、关联数组)之一来满足,但这些都不能像表一样使用。也就是说,您不能从它们中选择。

于 2008-10-21T19:25:05.083 回答
1

我相信全局临时表是一样的。他们将为您提供对会话结束时终止的临时表的私有访问权限:

全局临时表中的数据是私有的,因此会话插入的数据只能由该会话访问。全局临时表中特定于会话的行可以为整个会话保留,也可以只为当前事务保留。ON COMMIT DELETE ROWS 子句指示应在事务结束时删除数据。

再读几次问题后,我认为这是主要区别,也许您的问题是临时表在会话之间持续存在。因此,正如您在 Oracle 中想象的那样,不可能完全等价于:

CREATE GLOBAL TEMPORARY TABLE my_temp_table ON COMMIT DELETE ROWS select * from other table;

即使通过会话,该表将一直存在,直到它被删除,尽管其中的数据没有。相反,您需要提前创建临时表。

于 2008-10-21T13:28:06.023 回答
1

Oracle 中的临时表模型有些不同,它以“CREATE GLOBAL TEMPORARY TABLE..”语句为中心。临时表定义始终是全局的,但数据始终是会话私有的,并且数据是否在提交时保留取决于是否指定了限定条件“提交时保留行”或“提交时删除行”。

我在我的博客上有一些 Perl 脚本和一篇探索特定行为或 Oracle 临时表的文。

于 2008-10-22T13:38:34.533 回答
0

是的,卡森说得对。全局临时表仅对创建它们的会话可见,并在第一次提交或回滚时或在会话结束时消失。您可以在创建 gtt 时进行设置。

于 2008-10-21T13:30:31.820 回答