存储过程 oracle 11g 中的 TEMP 表

Posted

技术标签:

【中文标题】存储过程 oracle 11g 中的 TEMP 表【英文标题】:TEMP table in stored procedure oracle 11g 【发布时间】:2020-05-15 06:32:02 【问题描述】:

有没有办法用存储过程创建一个临时表,并在同一个存储过程的 ref 游标中使用它。 我写了类似下面的东西,它不起作用....

    CREATE OR REPLACE PROCEDURE USP_TEST(
    CUR_QUOTE OUT SYS_REFCURSOR) AS 
    BEGIN
    CREATE GLOBAL TEMPORARY TABLE users1 ON COMMIT PRESERVE ROWS
    AS
      SELECT 'rb@bot.com' FROM DUAL;
      OPEN CUR_QUOTE FOR
      SELECT DISTINCT CREATEDBY
      FROM QUOTE
      WHERE TRUNC(DATEOFENQUIRY)=TRUNC(SYSDATE-1) AND CREATEDBY = users1.EMAIL;
    END;

最后删除临时表。 请建议一些示例代码... 继续编码:)

【问题讨论】:

您没有在过程中使用全局临时表(创建它除外),因此您可以对该表执行任何操作。如果您在游标中使用了临时表,并且在最后删除了临时表,那么在从调用程序块打开游标时,您将收到错误消息。因为此时会执行光标的查询。 您不能不直接在过程中执行 ddl。使用 EXECUTE IMMEDIATE 来执行此操作。 此外,我建议您不要动态创建对象,除非您必须这样做。在这里,我想说你不必这样做。在程序之外创建它,在程序内部使用它。 通常情况下,临时表是错误的开始方法 【参考方案1】:

如果你删除表,那么游标就会失效。

从 18c 开始你可以使用private temporary tables:

create or replace procedure usp_test
    ( cur_quote out sys_refcursor )
as
begin
    execute immediate
        'create private temporary table ora$ptt_demo' ||chr(10)||
        'on commit drop definition as' ||chr(10)||
        'select sysdate -1 as dateofenquiry, ''rb@bot.com'' as createdby' ||chr(10)||
        'from   dual';

    open cur_quote for
        'select distinct createdby from ora$ptt_demo where trunc(dateofenquiry) = trunc(sysdate - 1)';
end;

请注意,表名必须有PRIVATE_TEMP_TABLE_PREFIX参数定义的前缀(默认ORA$PTT_),并且您必须在第二次调用该过程之前提交。

【讨论】:

以上是关于存储过程 oracle 11g 中的 TEMP 表的主要内容,如果未能解决你的问题,请参考以下文章

Oracle 11g 学习3——表空间操作

Oracle 中临时表的替代方案

oracle11g给某个用户创建表空间

存储过程中的光标完成并卡住(Oracle Linux VM 上的 Oracle 11g)

在 Oracle 存储过程中比较 IF 语句中的两列

Oracle 11g的一些常用语句记录