创建与现有表具有相同表结构的Oracle临时表

创建与现有表具有相同表结构的Oracle临时表,oracle,oracle18c,Oracle,Oracle18c,如何创建与现有表具有相同表结构的全局临时表 我知道这个概念在SQL server中可用,比如abc的select*into temp123。但是我想在Oracle中执行相同的操作。Oracle中的全局临时表与SQL Server中的临时表非常不同。它们是永久性的数据结构,只是其中的数据暂时限于会话或事务,具体取决于表的定义方式 Create global temporary table mytemp as select * from myTable where 1=2 因此,使用全局临时表

如何创建与现有表具有相同表结构的全局临时表


我知道这个概念在SQL server中可用,比如abc的select*into temp123。但是我想在Oracle中执行相同的操作。

Oracle中的全局临时表与SQL Server中的临时表非常不同。它们是永久性的数据结构,只是其中的数据暂时限于会话或事务,具体取决于表的定义方式

Create global temporary table mytemp 
as 
select * from myTable
where 1=2
因此,使用全局临时表的正确方式与在SQL Server中使用临时表的方式大不相同。CREATEGLOBAL TEMPORATE TABLE语句与任何其他表一样,是一次性的练习。在Oracle中,动态删除和重新创建表是一种不好的做法,而Oracle是这样做的

鉴于全局临时表的创建应该是一次性的,使用CREATETABLE并没有任何实际的好处。。。作为选择语法。语句应该被显式定义,脚本应该像其他DDL一样存储在源代码管理中

您已经标记了您的问题[oracle18c]。如果您真的在使用Oracle 18c,那么您将有一个新功能,即专用临时表,它更接近SQL Server临时表。这些表真正在内存中,并根据定义在事务或会话结束时自动删除。这些都有报道,但这里是标题

使用永久表T23中的数据子集创建专用临时表数据:

ORA$PTT前缀是必需的,尽管可以通过设置init.ORA参数PRIVATE_TEMP_TABLE_prefix来更改它,但是为什么还要麻烦呢

之后,我们可以在表上执行任何常规DML:

select * from ORA$PTT_t23;
最大的限制是我们不能在静态PL/SQL中使用表。该表本身不存在于数据字典中,因此PL/SQL编译器抛出(即使对于匿名块):

declare 
    rec t23%rowtype;
begin
    select * 
    into rec
    from ORA$PTT_t23';
    dbms_output.put_line('id = ' || rec.id);
end;
/
ORA-06550:第6行第10列:PL/SQL:ORA-00942:表或视图不存在

PL/SQL中对私有临时表的任何引用都必须使用动态SQL完成:

declare 
    n pls_integer;
begin
    execute immediate 'select id from ORA$PTT_t23' into n;
    dbms_output.put_line('id = ' || n);
end;
/

基本上,这将它们的使用限制为SQL*Plus或运行一系列纯SQL语句的脚本。所以,如果您有一个适合的用例,那么您应该检查私有临时表。但是,请考虑Oracle在很多方面与SQL Server不同,尤其是它的多版本一致性模型:阅读器不会阻止写入器。因此,Oracle中对临时表的需求大大减少。

在SQL Server的语法中,表名temp123中的前缀哈希表示-创建只能通过当前会话访问的临时表表示全局

Create global temporary table mytemp 
as 
select * from myTable
where 1=2
要在Oracle中实现完全相同的功能,您可以使用:

之后,您可以在SQL和PL/SQL块中使用这些表:

declare
    r mytab%rowtype;
begin 
    insert into ora$ptt_mytab values (2, 'bbb');
    select id + 1, name||'x' into r from ora$ptt_mytab where rownum = 1;
    insert into ora$ptt_mytab values r;
end;
/
select * from mytab
union all
select * from ora$ptt_mytab;

        ID NAME                            
---------- --------------------------------
         1 aaa                             
         2 bbb                             
         3 bbbx                            
对专用临时表的一些重要限制:

名称必须始终以参数PRIVATE_TEMP_TABLE_PREFIX定义的内容作为前缀。默认值为ORA$PTT\ux

不能在命名PL/SQL块的静态语句中引用PTT,例如包、函数或触发器

%ROWTYPE属性不适用于该表类型

不能使用默认值定义列


年引入了专用临时表18c@BobC我知道,这个主题被标记为18c。
declare
    r mytab%rowtype;
begin 
    insert into ora$ptt_mytab values (2, 'bbb');
    select id + 1, name||'x' into r from ora$ptt_mytab where rownum = 1;
    insert into ora$ptt_mytab values r;
end;
/
select * from mytab
union all
select * from ora$ptt_mytab;

        ID NAME                            
---------- --------------------------------
         1 aaa                             
         2 bbb                             
         3 bbbx