Tuesday, February 8, 2011

Generate DDLs (.SQL file) for every procedures and functions using DBMS_METADATA.

This is based on one of my posting in OTN. This shows, how to use DBMS_METADATA and DBMS_LOB.
This PL/SQL block generates a SQL file (with / character at the end of every object) for every functions and procedures.


/***************************************************************
 Generate a SQL file with ddls for any Procedures and Functions.
 This can be extended to get ddls of any objects.
****************************************************************/
DECLARE
--These varriables are to manipulate the LOBs
  myddls     CLOB := EMPTY_CLOB();
  metadata   CLOB := EMPTY_CLOB();
  ddls       CLOB := EMPTY_CLOB();
  v_amount   INTEGER;
  v_offset   INTEGER; -- Where to write.
  l_pos      INTEGER := 1;
  my_var     VARCHAR2(32767) := '/'; --Adding the / at the end.
  l_clob_len INTEGER;
  l_buffer   VARCHAR2(32767);
  l_amount   BINARY_INTEGER := 32767;

  --The cursor to fetch the object to get the DDLs.
  CURSOR cur_objcts IS
    SELECT object_name, object_type, owner
      FROM dba_objects
     WHERE object_type IN ('PROCEDURE', 'FUNCTION')
       AND owner IN ('SCOTT', 'HR'); --I am taking two schemas here. You can remove this restriction.

  --This function usages dbms_metadata to fetch the DDLs.
  FUNCTION get_metadata(pi_obj_type  IN VARCHAR2,
                        pi_obj_name  IN VARCHAR2,
                        pi_obj_owner IN VARCHAR2) RETURN CLOB IS
    h   NUMBER;
    th  NUMBER;
    doc CLOB;
  BEGIN
    h := DBMS_METADATA.open(pi_obj_type);
    DBMS_METADATA.set_filter(h, 'SCHEMA', pi_obj_owner);
    DBMS_METADATA.set_filter(h, 'NAME', pi_obj_name);
    th  := DBMS_METADATA.add_transform(h, 'MODIFY');
    th  := DBMS_METADATA.add_transform(h, 'DDL');
    doc := DBMS_METADATA.fetch_clob(h);
    DBMS_METADATA.CLOSE(h);
    return doc;
  END get_metadata;
 
------Begin main executable section.
BEGIN
  DBMS_LOB.createtemporary(myddls, TRUE);
  DBMS_LOB.createtemporary(metadata, TRUE);
  DBMS_LOB.open(myddls, DBMS_LOB.lob_readwrite);
  DBMS_LOB.open(metadata, DBMS_LOB.lob_readwrite);
  FOR i IN cur_objcts LOOP
    ddls := get_metadata(i.object_type, i.object_name, i.owner);
    --Get the total length of the CLOB
    l_clob_len := DBMS_LOB.getlength(ddls);
    --Read and Write in chunks.
    WHILE l_pos < l_clob_len LOOP
      DBMS_LOB.READ(ddls, l_amount, l_pos, l_buffer);
      DBMS_LOB.WRITE(metadata, l_amount, l_pos, l_buffer);
      l_pos := l_pos + l_amount;
    END LOOP;
    l_pos := 1;
    --append to another LOB
    DBMS_LOB.append(myddls,metadata);
    v_amount := DBMS_LOB.GETLENGTH(my_var);
    --Write the / character.
    DBMS_LOB.writeappend(myddls, v_amount, my_var);
 
  END LOOP;
  --Write the whle LOB to disk.
  DBMS_XSLPROCESSOR.clob2file(cl => myddls,flocation =>'SAUBHIK' ,fname =>'myddls.sql' );
 --Cleanups.
  DBMS_LOB.close(myddls);
  DBMS_LOB.close(metadata);
  DBMS_LOB.freetemporary(myddls);
  DBMS_LOB.freetemporary(metadata);

END;

No comments :

Post a Comment