2015-11-19 106 views
0

我需要在Oracle中临时存储查询的输出(它将返回多行)。其中一种方法是使用临时表,我目前正在使用临时表。但与他们的问题是,他们呆在周围,不能创建和放弃在一个程序很不错。是否有另一个对象可用于临时存储查询的输出以便能够在存储过程中使用?Oracle中的临时存储?

这里是我的存储关于参考操作:

create or replace PROCEDURE procPrintOutput 
IS 
    l_stmt VARCHAR2(512) := ''; 
    create_table_stmt VARCHAR2(512) := 'create GLOBAL TEMPORARY TABLE temp(matViewLogQuery CLOB) ON COMMIT DELETE ROWS'; 
    drop_mat_view_logs_stmt VARCHAR2(100) := 'DROP MATERIALIZED VIEW LOG ON '; 
    drop_temp_table VARCHAR2(512) := 'DROP TABLE temp'; 

    ref_cursor SYS_REFCURSOR; 
BEGIN 
    EXECUTE IMMEDIATE(create_table_stmt); 
    DBMS_OUTPUT.PUT_LINE('created temp table'); 
    DECLARE 
    CURSOR LIST_OF_MVL IS SELECT * FROM USER_MVIEW_LOGS; 
    CURSOR CREATE_MVL IS SELECT * FROM temp; 
    BEGIN 
      FOR TEST IN LIST_OF_MVL 
      LOOP 
      BEGIN 
       DBMS_OUTPUT.PUT_LINE('owner : ' || TEST.OWNER || ' - name : ' || TEST.MASTER); 
       l_stmt := 'insert into temp SELECT SYS.DBMS_METADATA.get_dependent_ddl (''MATERIALIZED_VIEW_LOG'', '''||TEST.MASTER||''', '''||TEST.LOG_OWNER||''') from dual'; 
       EXECUTE IMMEDIATE (l_stmt); 
       EXECUTE IMMEDIATE (drop_mat_view_logs_stmt || TEST.MASTER); 
       DBMS_OUTPUT.PUT_LINE('view dropped ... '); 
      END; 
      END LOOP; 

     FOR CREATE_SCRIPT IN CREATE_MVL 
     LOOP 
      BEGIN 
      DBMS_OUTPUT.PUT_LINE('SCRIPT : ' || CREATE_SCRIPT.matViewLogQuery); 
      EXECUTE IMMEDIATE(CREATE_SCRIPT.matViewLogQuery); 
      DBMS_OUTPUT.PUT_LINE('view recreated ... '); 
      END; 
     END LOOP; 
    END;   
    EXECUTE IMMEDIATE(drop_temp_table);  
    DBMS_OUTPUT.PUT_LINE('Done! Table dropped'); 
    ROLLBACK;   
END; 

感谢

+5

绝对没有必要不断地创建和删除临时表。只需创建一次并完成它。 –

+2

“但他们的问题是,他们留在身边,不能创建并在一个程序中被愚蠢地丢弃”而这是一个问题,为什么? –

+1

动态运行时创建数据库对象(如临时表)在某些数据库环境中可以接受,但在Oracle中不可接受。在Oracle中是一个(不幸的是)[反模式](https://en.wikipedia.org/wiki/Anti-pattern)。 – user272735

回答

0

,而不是临时表,你可以使用收集PL/SQL和存储您通过BULK COLLECT

需要到集合中的所有信息

在这里小编example

在我的例子中,我收集的意见matviews和名称的所有的DDL中, n在简单的循环中我们可以做任何操作...

DECLARE 
    TYPE tDDL IS record (name varchar2(30), ddl CLOB); 
    TYPE tblDDL IS TABLE OF tDDL INDEX BY PLS_INTEGER; 
    l_ddls tblDDL; 
BEGIN 

    SELECT object_name, dbms_metadata.get_ddl('MATERIALIZED_VIEW', object_name) 
    BULK COLLECT INTO l_ddls 
    from user_objects  
     where object_type= 'MATERIALIZED VIEW'; 

    FOR indx IN 1 .. l_ddls.COUNT 
    LOOP 
     --do what you need with collected DDLs 
     DBMS_OUTPUT.PUT_LINE('view dropped ... '); 

     --your complex execute immediate logic here      
     dbms_output.put(l_ddls(indx).name); 
     dbms_output.put('  :  '); 
     dbms_output.put_line(substr(l_ddls(indx).ddl, 100)); 

     DBMS_OUTPUT.PUT_LINE('view recreated ... '); 
    END LOOP; 
END;