|
|
|||||||||||||
|
|
One who is familiar with simple diff commands, can see how easy this would be to quickly compare these two objects. In fact, when these new APIs came out I quickly developed a function that would make use of this to perform a diff between two tables. Quickly my 100's of line of SQL became only 66 lines of code in a function. While it would be interesting to show the function here, it would be archaic as Oracle has now extended the DBMS_METADATA functions with the DBMS_METADATA_DIFF functions to include a set of calls that now allow DBAs to get the differences in objects in one simple SQL statement. As an example, the following is all that is needed to compare the DDL between TABLEONE and TABLETWO:
SQL> SELECT DBMS_METADATA_DIFF.COMPARE_SXML('TABLE','TABLEONE','TABLETWO') FROM dual;
<TABLE xmlns="http://xmlns.oracle.com/ku" version="1.0">
<SCHEMA>SYS</SCHEMA>
<NAME value1="TABLEONE">TABLETWO</NAME>
<RELATIONAL_TABLE>
<COL_LIST>
<COL_LIST_ITEM>
<NAME>ID</NAME>
<DATATYPE>NUMBER</DATATYPE>
</COL_LIST_ITEM>
<COL_LIST_ITEM>
<NAME>NAME</NAME>
<DATATYPE>VARCHAR2</DATATYPE>
<LENGTH>50</LENGTH>
</COL_LIST_ITEM>
<COL_LIST_ITEM src="2">
<NAME>PRICE</NAME>
<DATATYPE>NUMBER</DATATYPE>
</COL_LIST_ITEM>
</COL_LIST>
<PRIMARY_KEY_CONSTRAINT_LIST>
<PRIMARY_KEY_CONSTRAINT_LIST_ITEM src="1">
<NAME>TABLEONE_PK</NAME>
<COL_LIST>
<COL_LIST_ITEM>
<NAME>ID</NAME>
</COL_LIST_ITEM>
</COL_LIST>
<USING_INDEX>
<INDEX_ATTRIBUTES>
<PCTFREE>10</PCTFREE>
<INITRANS>2</INITRANS>
<STORAGE>
<INITIAL>65536</INITIAL>
<NEXT>1048576</NEXT>
<MINEXTENTS>1</MINEXTENTS>
<MAXEXTENTS>2147483645</MAXEXTENTS>
<PCTINCREASE>0</PCTINCREASE>
<FREELISTS>1</FREELISTS>
<FREELIST_GROUPS>1</FREELIST_GROUPS>
<BUFFER_POOL>DEFAULT</BUFFER_POOL>
<FLASH_CACHE>DEFAULT</FLASH_CACHE>
<CELL_FLASH_CACHE>DEFAULT</CELL_FLASH_CACHE>
</STORAGE>
<TABLESPACE>SYSTEM</TABLESPACE>
<LOGGING>Y</LOGGING>
</INDEX_ATTRIBUTES>
</USING_INDEX>
</PRIMARY_KEY_CONSTRAINT_LIST_ITEM>
<PRIMARY_KEY_CONSTRAINT_LIST_ITEM src="2">
<NAME>TABLETWO_PK</NAME>
<COL_LIST>
<COL_LIST_ITEM>
<NAME>ID</NAME>
</COL_LIST_ITEM>
<COL_LIST_ITEM>
<NAME>NAME</NAME>
</COL_LIST_ITEM>
</COL_LIST>
<USING_INDEX>
<INDEX_ATTRIBUTES>
<PCTFREE>10</PCTFREE>
<INITRANS>2</INITRANS>
<STORAGE>
<INITIAL>65536</INITIAL>
<NEXT>1048576</NEXT>
<MINEXTENTS>1</MINEXTENTS>
<MAXEXTENTS>2147483645</MAXEXTENTS>
<PCTINCREASE>0</PCTINCREASE>
<FREELISTS>1</FREELISTS>
<FREELIST_GROUPS>1</FREELIST_GROUPS>
<BUFFER_POOL>DEFAULT</BUFFER_POOL>
<FLASH_CACHE>DEFAULT</FLASH_CACHE>
<CELL_FLASH_CACHE>DEFAULT</CELL_FLASH_CACHE>
</STORAGE>
<TABLESPACE>SYSTEM</TABLESPACE>
<LOGGING>Y</LOGGING>
</INDEX_ATTRIBUTES>
</USING_INDEX>
</PRIMARY_KEY_CONSTRAINT_LIST_ITEM>
</PRIMARY_KEY_CONSTRAINT_LIST>
<PHYSICAL_PROPERTIES>
<HEAP_TABLE>
<SEGMENT_ATTRIBUTES>
<PCTFREE>10</PCTFREE>
<PCTUSED>40</PCTUSED>
<INITRANS>1</INITRANS>
<STORAGE>
<INITIAL>65536</INITIAL>
<NEXT>1048576</NEXT>
<MINEXTENTS>1</MINEXTENTS>
<MAXEXTENTS>2147483645</MAXEXTENTS>
<PCTINCREASE>0</PCTINCREASE>
<FREELISTS>1</FREELISTS>
<FREELIST_GROUPS>1</FREELIST_GROUPS>
<BUFFER_POOL>DEFAULT</BUFFER_POOL>
<FLASH_CACHE>DEFAULT</FLASH_CACHE>
<CELL_FLASH_CACHE>DEFAULT</CELL_FLASH_CACHE>
</STORAGE>
<TABLESPACE>SYSTEM</TABLESPACE>
<LOGGING>Y</LOGGING>
</SEGMENT_ATTRIBUTES>
<COMPRESS>N</COMPRESS>
</HEAP_TABLE>
</PHYSICAL_PROPERTIES>
</RELATIONAL_TABLE>
</TABLE>
Granted this is in XML and many a DBA have semi-difficulty reading this. However, a couple of simple scans or use of a XML/SXML viewer proves quite usesful. While this is very handy, the true power of these new functions would easily be the DBMS_METADATA_DIFF.COMPARE_ALTER function, which not only compares the differences between objects but gives a set of DDL commands required to alter one object so that it will equal the other object. As an example, we could issue the following SQL to get our TABLEONE table to equal our TABLETWO table:
SQL> SELECT DBMS_METADATA_DIFF.COMPARE_ALTER('TABLE','TABLEONE','TABLETWO') FROM dual;
ALTER TABLE "SYS"."TABLEONE" ADD ("PRICE" NUMBER)
ALTER TABLE "SYS"."TABLEONE" DROP CONSTRAINT "TABLEONE_PK"
ALTER TABLE "SYS"."TABLEONE" ADD CONSTRAINT "TABLETWO_PK" PRIMARY KEY ("ID","N
AME") USING INDEX PCTFREE 10 INITRANS 2 STORAGE ( INITIAL 65536 NEXT 1048576 MIN
EXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFF
ER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) ENABLE
ALTER TABLE "SYS"."TABLEONE" RENAME TO "TABLETWO"
The DBMS_METADATA_DIFF becomes a VERY POWERFUL weapon in the hands of a DBA, simplifying many of the headaches involved in database change control. In their most basic form, the syntax for these two APIs, with the following parameters, become: DBMS_METADATA_DIFF.COMPARE_SXML( object_type IN VARCHAR2, name1 IN VARCHAR2, name2 IN VARCHAR2) DBMS_METADATA_DIFF.COMPARE_ALTER( object_type IN VARCHAR2, name1 IN VARCHAR2, name2 IN VARCHAR2)
DBMS_METADATA_DIFF is, in Oracle 11gR2, a form of extension to DBMS_METADATA but does require a license to the Oracle Enterprise Manager Change Management option. Now you don't have to use these but the time saved in change management alone will surely make up for the additional licensing. Additional Resources
DDL Generation--Oracle's Answer to Save You Time and Money
|
|||||||||||||||||||||||||||||||||||||||||||||||||||
![]() |
![]()