Несколько наборов результатов из Oracle в Odp.net, без прекурсоров - PullRequest
4 голосов
/ 23 марта 2010

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 Ответ

6 голосов
/ 25 марта 2010

В Oracle ссылочный курсор - это указатель на данные, а не сами данные. Таким образом, если процедура возвращает два ссылочных курсора, клиент все равно должен пойти и извлечь строки из этих курсоров (и подвергнуться ударам сети).

Таким образом, если объемы данных невелики, вы, вероятно, захотите вызвать процедуру, которая просто возвращает значения. Если объемы данных велики (тысячи строк), то это все равно будет не одно сетевое отключение, поэтому дополнительные один или два при переключении между курсорами не будут иметь большого значения.

Другой вариант - один выбор, возвращающий все строки. Это может быть простой Союз ВСЕ

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 для 11g допускают определяемые пользователем типы, которые могут помочь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...