Может ли программа Oracle возвращать результаты из глобальной временной таблицы

Вот кусок кода Oracle, который я пытаюсь адаптировать. Я сократил все детали:

    declare  
    begin  
      loop  
      --do stuff to populate a global temporary table.  I'll call it 'TempTable'  
      end loop;  
    end; 
    /

   Select * from TempTable

Прямо сейчас этот запрос работает нормально, если я запускаю его в два этапа. Сначала я запускаю программу сверху, затем я запускаю select *, чтобы получить результаты.

Можно ли объединить две части, чтобы я мог заполнить глобальную временную таблицу и получить результаты за один шаг?

Заранее спасибо!


person Mark Broski    schedule 18.04.2011    source источник
comment
Вы пытаетесь вернуть этот набор результатов клиентской программе (используя курсор ссылки). Когда вы говорите «извлечь», вы хотите увидеть результаты в таком инструменте, как TOAD?   -  person Rajesh Chamarthi    schedule 19.04.2011


Ответы (3)


Ну, для меня это зависит от того, как я буду видеть шаги. Вы выполняете команду PL/SQL и SQL. Я бы предпочел ввести их в файл и запустить их одной командой (если бы это можно было назвать для вас одним шагом)...

Что-то вроде

файл.sql

begin  
 loop  
 --do stuff to populate a global temporary table.  I'll call it 'TempTable'  
 end loop;  
end; 
/
Select * 
from TempTable
/

И запустите его как:

prompt> sqlplus /@db @file.sql

Если вы предоставите нам более подробную информацию, например, как заполнить GTT, возможно, мы найдем способ сделать это за один шаг.

person Guru    schedule 18.04.2011
comment
Ей-богу, добавление этой косой черты в конец, кажется, решило эту проблему. Огромное спасибо! - person Mark Broski; 19.04.2011

Да, но это не тривиально.

create global temporary table my_gtt
 ( ...  )
on commit preserve rows;

create or replace type my_gtt_rowtype as object
  ( [columns definition] )
/

create or replace type my_gtt_tabtype as table of my_gtt_rowtype
/

create or replace function pipe_rows_from_gtt
  return my_gtt_tabtype 
  pipelined
is
  pragma autonomous_transaction;
  type rc_type is refcursor;
  my_rc rc_type;
  my_output_rec my_gtt_rectype := my_gtt_rectype ([nulls for each attribute]);
begin
  delete from my_gtt;
  insert into my_gtt ...
  commit;
  open my_rc for select * from my_gtt;

  loop
    fetch my_rc into my_output_rec.attribute1, my_output_rec.attribute1, etc;
    exit when my_rc%notfound;
    pipe_row (my_output_rec);
  end loop;
  close my_rc;
  return;
end;
/

Я не знаю, требуется ли прагма автономной транзакции, но я подозреваю, что это так, иначе она будет выдавать ошибки о функциях, выполняющих DML.

Мы используем такой код, чтобы иметь механизмы отчетов, которые не могут выполнять процедурную логику построения глобальных временных таблиц, которые они используют (и повторно используют) в различных подотчетах.

person Adam Musch    schedule 19.04.2011

В Oracle очень редко требуется дополнительная таблица для хранения промежуточных результатов. Это может помочь облегчить понимание. Когда вы можете написать SQL для заполнения промежуточной таблицы, вы, безусловно, можете запросить строки за один шаг, не тратя время на заполнение GTT. Если вы используете pl/sql для заполнения GTT, посмотрите, можно ли это исправить, чтобы он был чистым SQL. Это почти наверняка даст вам преимущество в производительности.

person ik_zelf    schedule 19.04.2011