【问题标题】:PL/SQL - caching two resultsets into collections and joining them together?PL/SQL - 将两个结果集缓存到集合中并将它们连接在一起?
【发布时间】:2010-02-24 18:16:36
【问题描述】:

我有两个非常大的表,我需要从这些表中处理一个小的结果集。然而,处理是在几个函数中完成的,并且函数必须进行一些连接才能以正确的方式格式化数据。

我肯定需要以某种方式缓存初始结果集,以便函数可以重用它。我想做的是将第一个结果集放在一个集合中,将第二个结果集放在另一个集合中,然后通过 SQL 查询操作这些集合,就好像它们是真正的 SQL 表一样。

您能建议如何做到这一点吗?

【问题讨论】:

    标签: sql database oracle collections plsql


    【解决方案1】:

    听起来像是临时表的工作:

    CREATE GLOBAL TEMPORARY TABLE table_name (...) ON ...
    

    ON 有两个选项,影响不同:

    1. ON COMMIT DELETE ROWS 指定临时表将是特定于事务的。数据在表中一直持续到事务结束时间。如果您结束事务,数据库将截断表(删除所有行)。假设如果您发出 commit 或运行 ddl,那么临时表中的数据将丢失。这是默认选项。

    2. ON COMMIT PRESERVE ROWS 指定临时表将是特定于会话的。数据在表中一直持续到会话结束时间。如果您结束会话,数据库将截断表(删除所有行)。假设您在 SQL*Plus 中键入 exit,那么临时表中的数据将会丢失。

    参考:

    ...但您可能不需要使用临时表。派生表/内联视图/子查询(可能是流水线)可能会做你想做的事,但信息很模糊,所以我不能推荐一种特定的方法。

    【讨论】:

      【解决方案2】:

      如果您的集合是用 SQL 类型声明的,您可以在带有 TABLE() 函数的 SQL 语句中使用它们。在 Oracle 10g 中,我们可以使用 MULTISET UNION 运算符合并集合。以下代码显示了这两种技术的示例...

      SQL> declare
        2      v1 sys.dbms_debug_vc2coll;
        3      v2 sys.dbms_debug_vc2coll;
        4      v3 sys.dbms_debug_vc2coll := sys.dbms_debug_vc2coll();
        5  begin
        6      select ename
        7      bulk collect into v1
        8      from emp;
        9      select dname
       10      bulk collect into v2
       11      from dept;
       12
       13      -- manipulate connects using SQL
       14
       15      for r in ( select * from table(v1)
       16                 intersect
       17                 select * from table(v2)
       18               )
       19      loop
       20          dbms_output.put_line('Employee '|| r.column_value ||' has same name as a department');
       21      end loop;
       22
       23      -- combine two collections into one
       24
       25      dbms_output.put_line('V3 has '|| v3.count() ||' elements');
       26      v3 := v1 multiset union v2;
       27      dbms_output.put_line('V3 now has '|| v3.count() ||' elements');
       28  end;
       29  /
      Employee SALES has same name as a department
      V3 has 0 elements
      V3 now has 23 elements
      
      PL/SQL procedure successfully completed.
      
      SQL>
      

      您可以采用许多其他方法。作为一项规则,最好使用 SQL 而不是 PL/SQL,因此 OMG Ponies 建议的临时表可能是合适的。这实际上取决于您处理需求的具体细节。

      【讨论】:

        【解决方案3】:

        您需要创建一个模式级别的类型(不在包内)作为嵌套表。您可以填充它们,然后您可以使用“table()”语句在查询中将它们用作普通表。

        link 解释了您的需求。一个简单的例子

        create type foo as table of number;-- or a record type, data%rowtype, whatever
        ...
        myfoo1 foo := foo (1,2,3);
        myfoo2 foo := foo(3,4,5)
        
        select column_value
        into bar
        from table(foo1) join table(foo2) using (column_value)
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2018-08-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-01-20
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多