views:

1475

answers:

2

Ok, so i'm a complete newb with oracle. Now that that's out of the way;

I think you can get an understand of what i'm trying to do below. For each stored procedure found, output the DDL to a filename with it's name.

The problem is i can't figure out how to get the spool target to pick up the value of FileName which is being set by the cursor.

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;

Any ideas as to where i'm going wrong? and if anyone has an example of this i would appreciate it greatly.

I feel i must be dancing around it because if i create a column initially then

spool &ColName

i get a result, i just can't seem to dynmically change that &colname

Thanks for your help.

+3  A: 

SPOOL is a SQL*Plus directive and you can't mix it into the PL/SQL anonymous block. If you're going to do this purely in SQL*Plus, I think the general idea would be to process in two passes, i.e. use a first script that dynamically generates the spool filename references into a second script that actually makes the dbms_metadata call.

[Edit]

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
dpbradley
Damn. well, ok thanks.
Beta033
hey - it's not THAT hard - I'll edit my answer with something close enough to get you started
dpbradley
+2  A: 

I think UTL_FILE would be much better suited for your needs here. SPOOL is really supposed to be a command to instruct sqlplus to write the output to a file. Typically I use this for stuff like ... "hey DBA run my script and send me the output".

First you need to define a directory. Syntax is easy:


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

Now you can use that in your code:


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;
David