在PL / SQL中创建临时表

时间:2010-08-11 19:36:12

标签: sql oracle plsql oracle10g temp-tables

我正在使用Oracle 10g数据库,我想从一个表中提取一组记录,然后使用它来从一堆相关表中提取记录。

如果这是T-SQL,我会这样做:

CREATE TABLE #PatientIDs (
  pId int
)

INSERT INTO #PatientIDs
  select distinct pId from appointments

SELECT * from Person WHERE Person.pId IN (select pId from #PatientIDs)

SELECT * from Allergies WHERE Allergies.pId IN (select pId from #PatientIDs)

DROP TABLE #PatientIDs

然而,我看到的所有有用的页面都让它看起来比它可能的工作要多得多,所以我想我一定会错过一些明显的东西。

(顺便说一句,我可能会在Oracle SQL Developer中打开一个会话,创建临时表,然后运行每个查询,然后将它们导出到CSV中。而不是将其作为一个脚本运行。工作?)

3 个答案:

答案 0 :(得分:12)

Oracle有临时表,但它们需要显式创建:

create global temporary table...

临时表中的数据对于创建它的会话是私有的,可以是特定于会话的或特定于事务的。如果要在会话结束前删除 数据,则需要在create语句末尾使用ON COMMIT PRESERVE ROWS。它们也没有回滚或提交支持......

我认为你给出的示例中不需要临时表 - 因为临时表的填充不会反映出对APPOINTMENTS表所做的更新的风险。使用IN / EXISTS / JOIN:

SELECT p.* 
  FROM PERSON p
 WHERE EXISTS (SELECT NULL
                 FROM APPOINTMENTS a
                WHERE a.personid = a.id)

SELECT p.* 
  FROM PERSON p
 WHERE p.personid IN (SELECT a.id
                        FROM APPOINTMENTS a)

SELECT DISTINCT p.* 
  FROM PERSON p
  JOIN APPOINTMENTS a ON a.id = p.personid

如果有多个APPOINTMENT记录与单个PERSON记录关联,则加入风险重复,这就是我添加DISTINCT的原因。

答案 1 :(得分:6)

Oracle没有以与SQL Server相同的方式随意创建临时表的功能。您必须在数据库模式(create global tempory table)中显式创建表。这也意味着您需要允许创建表的权限,并且必须将脚本显式部署为数据库更改。该表在全局名称空间中也可见。

这是Oracle和SQL Server编程之间的重要区别。惯用语T-SQL可以广泛使用临时表,并且编写程序性T-SQL代码的真正要求非常少见,主要是因为这种设施。

惯用PL / SQL可以更快地退出程序代码,你可能会比尝试伪造临时表更好。请注意,PL / SQL具有面向性能的构造,例如用于对游标进行显式并行处理的流控制和嵌套结果集(游标表达式);最新版本有一个JIT编译器。

您可以访问一系列工具来快速运行程序PL / SQL代码,这可以说是惯用的PL / SQL编程。底层范例与T-SQL略有不同,临时表的方法是系统架构和编程习惯不同的主要方面之一。

答案 2 :(得分:5)

虽然确切的问题已经解决了,如果你想在这方面建立一些有用的技能,我会看看PL / SQL集合,特别是使用pl / sql集合的批量SQL操作(BULK COLLECT / Bulk)绑定),RETURNING子句,以及使用%ROWTYPE定义集合。

通过了解上述所有内容,您可以大大减少您编写的pl / sql代码的数量 - 尽管始终记住,全SQL解决方案几乎总是胜过PL / SQL解决方案。

相关问题