Placing Conditions on Transforms

You can use transform parameters to specify conditions on the transforms you add. To do this, you use the SET_TRANSFORM_PARAM procedure. For example, if you have added the DDL transform for a TABLE object, then you can specify the SEGMENT_ATTRIBUTES transform parameter to indicate that you do not want segment attributes (physical, storage, logging, and so on) to appear in the DDL. The default is that segment attributes do appear in the DDL.

Example 21-4 shows use of the SET_TRANSFORM_PARAM procedure.

Example 21-4 Placing Conditions on Transforms

  1. Create a function named get_table_md, as follows:

    CREATE OR REPLACE FUNCTION get_table_md RETURN CLOB IS
     -- Define local variables.
     h    NUMBER;   -- handle returned by 'OPEN'
     th   NUMBER;   -- handle returned by 'ADD_TRANSFORM'
     doc  CLOB;
    BEGIN
    
     -- Specify the object type. 
     h := DBMS_METADATA.OPEN('TABLE');
    
     -- Use filters to specify the particular object desired.
     DBMS_METADATA.SET_FILTER(h,'SCHEMA','HR');
     DBMS_METADATA.SET_FILTER(h,'NAME','TIMECARDS');
    
     -- Request that the metadata be transformed into creation DDL.
     th := dbms_metadata.add_transform(h,'DDL');
    
     -- Specify that segment attributes are not to be returned.
     -- Note that this call uses the TRANSFORM handle, not the OPEN handle.
    DBMS_METADATA.SET_TRANSFORM_PARAM(th,'SEGMENT_ATTRIBUTES',false);
    
     -- Fetch the object.
     doc := DBMS_METADATA.FETCH_CLOB(h);
    
     -- Release resources.
     DBMS_METADATA.CLOSE(h);
    
     RETURN doc;
    END;
    /
    
  2. Perform the following query:

    SQL> SELECT get_table_md FROM dual;
    

    The output looks similar to the following:

      CREATE TABLE "HR"."TIMECARDS"
       (    "EMPLOYEE_ID" NUMBER(6,0),
            "WEEK" NUMBER(2,0),
            "JOB_ID" VARCHAR2(10),
            "HOURS_WORKED" NUMBER(4,2),
             FOREIGN KEY ("EMPLOYEE_ID")
              REFERENCES "HR"."EMPLOYEES" ("EMPLOYEE_ID") ENABLE
       )
    

The examples shown up to this point have used a single transform, the DDL transform. The DBMS_METADATA API also enables you to specify multiple transforms, with the output of the first being the input to the next and so on.

Oracle supplies a transform called MODIFY that modifies an XML document. You can do things like change schema names or tablespace names. To do this, you use remap parameters and the SET_REMAP_PARAM procedure.

Example 21-5 shows a sample use of the SET_REMAP_PARAM procedure. It first adds the MODIFY transform and specifies remap parameters to change the schema name from hr to scott. It then adds the DDL transform. The output of the MODIFY transform is an XML document that becomes the input to the DDL transform. The end result is the creation DDL for the timecards table with all instances of schema hr changed to scott.

Example 21-5 Modifying an XML Document

  1. Create a function named remap_schema:

    CREATE OR REPLACE FUNCTION remap_schema RETURN CLOB IS
    -- Define local variables.
    h NUMBER; --handle returned by OPEN
    th NUMBER; -- handle returned by ADD_TRANSFORM
    doc CLOB;
    BEGIN
    
    -- Specify the object type.
    h := DBMS_METADATA.OPEN('TABLE');
    
    -- Use filters to specify the particular object desired.
    DBMS_METADATA.SET_FILTER(h,'SCHEMA','HR');
    DBMS_METADATA.SET_FILTER(h,'NAME','TIMECARDS');
    
    -- Request that the schema name be modified.
    th := DBMS_METADATA.ADD_TRANSFORM(h,'MODIFY');
    DBMS_METADATA.SET_REMAP_PARAM(th,'REMAP_SCHEMA','HR','SCOTT');
    
    -- Request that the metadata be transformed into creation DDL.
    th := DBMS_METADATA.ADD_TRANSFORM(h,'DDL');
    
    -- Specify that segment attributes are not to be returned.
    DBMS_METADATA.SET_TRANSFORM_PARAM(th,'SEGMENT_ATTRIBUTES',false);
    
    -- Fetch the object.
    doc := DBMS_METADATA.FETCH_CLOB(h);
    
    -- Release resources.
    DBMS_METADATA.CLOSE(h);
    RETURN doc;
    END;
    / 
    
  2. Perform the following query:

    SELECT remap_schema FROM dual;
    

    The output looks similar to the following:

      CREATE TABLE "SCOTT"."TIMECARDS"
       (    "EMPLOYEE_ID" NUMBER(6,0),
            "WEEK" NUMBER(2,0),
            "JOB_ID" VARCHAR2(10),
            "HOURS_WORKED" NUMBER(4,2),
             FOREIGN KEY ("EMPLOYEE_ID")
              REFERENCES "SCOTT"."EMPLOYEES" ("EMPLOYEE_ID") ENABLE
       )
    

    If you are familiar with XSLT, then you can add your own user-written transforms to process the XML.