ORACLE Как использовать спул с динамическим местоположением спула

Итак, я полный новичок в оракуле. Теперь, когда это не по пути;

Я думаю, вы можете понять, что я пытаюсь сделать ниже. Для каждой найденной хранимой процедуры выведите DDL в файл с ее именем.

Проблема в том, что я не могу понять, как заставить цель буфера получить значение FileName, которое устанавливается курсором.

DECLARE 
objName varchar2(50);
FileName varchar2(50);

cursor curProcs is
    select OBJECT_NAME into objName
      FROM ALL_PROCEDURES WHERE OWNER = 'AMS' 
      ORDER BY OBJECT_NAME; -- get all procs in db
BEGIN
open curProcs;
  if curProcs%ISOPEN THEN
   LOOP
    FETCH curProcs into objName;
    EXIT WHEN curProcs%NOTFOUND;
    FileName := 'C:\ ' || objName || '.PRC.SQL';
    spool FileName; --BREAKS
     DBMS_METADATA.GET_DDL('PROCEDURE',objName);
    spool off;
   END LOOP;
  END IF;
END; 

Есть идеи, где я ошибаюсь? и если у кого-то есть пример этого, я был бы очень признателен.

Я чувствую, что должен танцевать вокруг этого, потому что если я сначала создам столбец, то

spool &ColName

я получаю результат, я просто не могу динамически изменить это &colname

Спасибо за вашу помощь.


person Beta033    schedule 07.08.2009    source источник


Ответы (3)


SPOOL — это директива SQLPlus, и ее нельзя смешивать с анонимным блоком PL/SQL. Если вы собираетесь делать это исключительно в SQLPlus, я думаю, что общая идея будет состоять в том, чтобы обрабатывать в два прохода, т. е. использовать первый сценарий, который динамически генерирует ссылки на имена файлов буфера, во второй сценарий, который фактически делает вызов dbms_metadata.

[Редактировать]

This should be close to what you need - maybe a line termination problem, depending on your platform:

    set pagesize 0
    set linesize 300
    spool wrapper.sql
    select
    'spool '||object_name||'.sql'||chr(10)||
    'begin 
    dbms_metadata.get_ddl('||chr(39)||object_type||chr(39)||','||chr(39)||object_name||chr(39)||')'||' end;'||chr(10)||
    '/'||chr(10)||
    'spool off'
    from user_objects
    where object_type = 'PROCEDURE'
;
spool off
person dpbradley    schedule 07.08.2009
comment
эй - это не НАСТОЛЬКО сложно - я отредактирую свой ответ чем-то достаточно близким, чтобы вы начали - person dpbradley; 07.08.2009

Я нашел лучшее решение без необходимости объявлять/начинать/заканчивать блоки кода или запросы.

Образец имени файла спула с датой и временем можно получить следующим образом:


sql> column dt new_value _dt 
sql> select to_char(sysdate,'ddMONyyyy_hh24mi') dt from dual; 
sql> spool &_dt
Мое имя файла:

27JUN2011_1727.lst

Вы даже можете указать расширение файла, если вам нужно (например, .txt). Просто создайте другую переменную.

источник: http://oracle.ittoolbox.com/groups/technical-functional/oracle-apps-l/variable-file-name-with-spool-1508529

person sanc    schedule 27.06.2011
comment
+1 Это работает лучше для меня, так как не нужно создавать еще один скрипт, как в принятом ответе. - person Lukman; 20.10.2011

Я думаю, что UTL_FILE гораздо лучше подходит для ваших нужд. SPOOL на самом деле должен быть командой, которая указывает sqlplus записывать вывод в файл. Обычно я использую это для таких вещей, как ... "Эй, DBA, запусти мой скрипт и пришли мне результат".

Сначала вам нужно определить каталог. Синтаксис прост:


CREATE DIRECTORY SQLOUTPUT AS 'c:\temp\';

Теперь вы можете использовать это в своем коде:


DECLARE

  -- Get all procedure from All_Objects
  -- You could expand this to pass in the object_type you are looking for
  CURSOR csr IS
    SELECT object_type
      , object_name
    FROM All_Objects
    WHERE object_type = 'PROCEDURE'
    AND owner = 'AMS';

  -- define a file handler type
  outputfile UTL_FILE.file_type;

BEGIN

FOR c IN csr LOOP

  -- open your file using the procedure name from the cursor
  outputfile := UTL_FILE.fopen('SQLOUTPUT',c.object_name||'.prc.sql','W');

  -- output the metadata results just like DBMS_OUTPUT except to a file
  UTL_FILE.put_line(outputfile, DBMS_METADATA.get_ddl(c.object_type, c.object_name));

  -- make sure to close the file when you are done.
  UTL_FILE.fclose(outputfile);

END LOOP;
  -- go home early today ...
END;
person David    schedule 08.08.2009