代码之家  ›  专栏  ›  技术社区  ›  James L

在odp.net中有多个来自Oracle的结果集,没有refcursor

  •  4
  • James L  · 技术社区  · 16 年前

    SQL Server能够在一次往返中返回多个查询的结果,例如:

    select a, b, c from y;
    select d, e, f from z;
    

    Oracle不喜欢这种语法。可以使用引用光标,如下所示:

    begin 
      open :1 for select count(*) from a; 
      open :2 for select count(*) from b; 
    end; 
    

    但是,您在打开/关闭光标时会受到惩罚,并且您可以长时间持有数据库锁。我要做的是使用odp.net一次检索这两个查询的结果。有可能吗?

    1 回复  |  直到 16 年前
        1
  •  6
  •   Gary Myers    16 年前

    在Oracle中,引用光标是指向数据的指针,而不是指向数据本身。 因此,如果一个过程返回两个引用游标,客户机仍然需要从这些游标中获取行(并导致网络命中)。

    因此,如果数据量很小,您可能希望调用只返回值的过程。 如果数据量很大(数千行),那么它就不会是一次单独的网络访问,所以在光标之间切换时多加一两个不会有太大的区别。

    另一个选择是使用一个select返回所有行。那可能是一个简单的结合

    select a, b, c from y union all select d, e, f from z;
    

    它可以是一个流水线表函数

    create or replace package test_pkg is
        type rec_two_cols is record
            (col_a  varchar2(100),
            col_b       varchar2(100));
        type tab_two_cols is table of rec_two_cols;
        function ret_two_cols return tab_two_cols pipelined;
    end;
    /
    
    create or replace package body test_pkg is
        function ret_two_cols return tab_two_cols pipelined
        is
            cursor c_1 is select 'type 1' col_a, object_name col_b from user_objects;
            cursor c_2 is select 'type 2' col_a, object_name col_b from user_objects;
            r_two_cols  rec_two_cols;
        begin
            for c_rec in c_1 loop
                r_two_cols.col_a := c_rec.col_a;
                r_two_cols.col_b := c_rec.col_b;
                pipe row (r_two_cols);
            end loop;
            for c_rec in c_2 loop
                r_two_cols.col_a := c_rec.col_a;
                r_two_cols.col_b := c_rec.col_b;
                pipe row (r_two_cols);
            end loop;
            return;
        end;
    end;
    /
    select * from table(test_pkg.ret_two_cols);
    

    我相信最新版本的odp for 11g允许用户定义类型,这可能会有所帮助。