Oracle PL / SQL: выгрузить результат запроса в файл - PullRequest
3 голосов
/ 31 марта 2010

Я работаю над хранимой процедурой pl sql. Что мне нужно, это сделать выбор, использовать курсор и для каждой записи построить строку, используя значения. В конце мне нужно записать это в файл. Я пытаюсь использовать dbms_output.put_line ("toto"), но размер буфера слишком мал, потому что у меня около 14 миллионов строк. Я называю свою процедуру из unix ksh. Я думаю о чем-то вроде использования «spool on» (на стороне ksh) для вывода результата моей процедуры, но я не знаю, как это сделать (если это возможно)

У кого-нибудь есть идеи?

Ответы [ 4 ]

8 голосов
/ 31 марта 2010

Если бы это не было действительно необходимо, я бы не использовал процедуру.

Если вы вызываете скрипт с использованием SQL Plus, просто добавьте в ваш test.sql следующее (SET s от SQL Plus FAQ для удаления шума):

SET ECHO OFF
SET NEWPAGE 0
SET SPACE 0
SET PAGESIZE 0
SET FEEDBACK OFF
SET HEADING OFF
SET TRIMSPOOL ON
SET TAB OFF

Select owner || ';' || object_name
From all_objects;

QUIT

и перенаправить вывод в файл (test.txt):

sqlplus user/passwd@instance @ test.sql > test.txt

Если вам действительно нужно что-то делать в PL / SQL, подумайте над тем, чтобы поместить это в функцию и вызывать ее для каждой записи:

Create Or Replace Function calculate_my_row( in_some_data In Varchar2 )
  Return Varchar2
As
Begin
  Return in_some_data || 'something-complicated';
End calculate_my_row;

Звоните:

Select owner || ';' || calculate_my_row( object_name )
From all_objects;

Производительность может пострадать, но она должна работать. Убедитесь, что то, что вы пытаетесь сделать, не может быть сделано в чистом SQL, однако.


Читая ваш комментарий, я думаю, что аналитическая функция Lag - это то, что вам нужно.

Этот пример добавляет * в случае, если значение val изменилось:

With x As (
      Select 1 id, 'A' val FROM dual
Union Select 2 id, 'A' val FROM dual
Union Select 3 id, 'B' val FROM dual
Union Select 4 id, 'B' val FROM dual
)
--# End of test-data
Select
  id,
  val,
  Case When ( val <> prev_val Or prev_val Is Null ) Then '*' End As changed
From (
  Select id, val, Lag( val ) Over ( Order By id ) As prev_val
  From x
)
Order By id

Возвращает

        ID V C
---------- - -
         1 A *
         2 A  
         3 B *
         4 B  
1 голос
/ 31 марта 2010

Если каждая строка вашего вывода является результатом операции над одной строкой в ​​таблице, то сохраненная функция в сочетании с ответом Питера Ланга может сделать то, что вам нужно.

create function create_string(p_foobar foobar%rowtype) return varchar2 as
begin
  do_some_stuff(p_foobar);
  return p_foobar.foo || ';' ||p_foobar.bar;
end;
/

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

create type varchar_array
    as table of varchar2(2000)
/

create function output_pipelined return varchar_array PIPELINED as
  v_line varchar2(2000);
begin
  for r_foobar in (select * from foobar)
  loop
    v_line := create_string(r_foobar);
    pipe row(v_line);
  end loop;
  return;
end;
/ 

select * from TABLE(output_pipelined);  
0 голосов
/ 31 марта 2010

Том Кайт ответил на это, см.

Flat

из этот вопрос на вопрос Тома

0 голосов
/ 31 марта 2010

utl_file твой друг http://www.adp -gmbh.ch / ор / PLSQL / utl_file.html Но он записывает данные в файловую систему на сервере, поэтому вам, возможно, понадобится помощь вашего администратора БД.

...