在PL/SQL中创建临时表

Sar*_*can 6 sql oracle plsql temp-tables oracle10g

我正在使用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
Run Code Online (Sandbox Code Playgroud)

但是,我看到的所有有用的页面使得它看起来比它可能的工作要多得多,所以我认为我必须遗漏一些明显的东西.

(顺便说一下,我可能会在Oracle SQL Developer中打开一个会话,创建临时表,然后运行每个查询,在我继续时将它们导出为CSV.这样做会有效吗?)

OMG*_*ies 12

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

create global temporary table...
Run Code Online (Sandbox Code Playgroud)

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

我看到你给出的示例中不需要临时表 - 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
Run Code Online (Sandbox Code Playgroud)

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


Con*_*lls 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略有不同,临时表的方法是系统架构和编程习惯不同的主要方面之一.


Jul*_*sLt 5

虽然确切的问题已经解决了,如果你想在这个领域建立一些有用的技能,我想看看PL/SQL集合,并使用PL/SQL集合特别是大批量SQL操作(BULK COLLECT /批量绑定) RETURNING子句,并使用%ROWTYPE定义集合.

您可以显着降低的PL/SQL代码编写量通过了解以上所有的 - 虽然永远记住,全SQL解决方案几乎总是打一个PL/SQL之一.