When working with Oracle databases, developers often need to compare schemas to identify discrepancies. The standard approach using DBMS_METADATA.GET_DDL
can produce output with too many trivial differences (like schema names) that obscure meaningful changes.
Here's a more effective method that filters out insignificant differences while preserving the structural information you actually care about:
-- For tables
SELECT
DBMS_METADATA.GET_DDL('TABLE', table_name)
FROM
user_tables
ORDER BY
table_name;
-- For indexes (with schema name removed)
SELECT
REGEXP_REPLACE(
DBMS_METADATA.GET_DDL('INDEX', index_name),
'".*?"\.',
''
)
FROM
user_indexes
ORDER BY
index_name;
-- For triggers
SELECT
DBMS_METADATA.GET_DDL('TRIGGER', trigger_name)
FROM
user_triggers
ORDER BY
trigger_name;
For more precise comparisons, consider these additional strategies:
-- Compare table structures without storage parameters
SELECT
DBMS_METADATA.GET_DDL('TABLE', table_name, 'SCHEMA')
FROM
user_tables
WHERE
table_name NOT LIKE 'BIN$%' -- exclude recyclebin objects
ORDER BY
table_name;
Create a script to generate comparable output from both schemas:
SET LONG 100000
SET LONGCHUNKSIZE 100000
SET LINESIZE 1000
SET PAGESIZE 0
SET TRIMSPOOL ON
SET ECHO OFF
SET FEEDBACK OFF
SPOOL schema_compare_&_schema_name..sql
-- Generate normalized DDL for all objects
BEGIN
FOR t IN (SELECT table_name FROM user_tables ORDER BY table_name) LOOP
DBMS_OUTPUT.PUT_LINE(
REGEXP_REPLACE(
DBMS_METADATA.GET_DDL('TABLE', t.table_name),
'".*?"\.',
''
)
);
END LOOP;
FOR i IN (SELECT index_name FROM user_indexes ORDER BY index_name) LOOP
DBMS_OUTPUT.PUT_LINE(
REGEXP_REPLACE(
DBMS_METADATA.GET_DDL('INDEX', i.index_name),
'".*?"\.',
''
)
);
END LOOP;
END;
/
SPOOL OFF
For complex schemas, consider specialized tools like:
- Oracle SQL Developer's Database Diff feature
- Redgate Schema Compare for Oracle
- DBComparer
Remember to:
- Compare objects in a consistent order
- Normalize whitespace and formatting
- Exclude system-generated objects
- Consider using checksums for large objects
When working with complex Oracle databases, schema drift between environments is a common headache. The native approach using DBMS_METADATA often produces noisy diffs due to schema name inclusion and formatting variations. Here's how to get clean, comparable output.
The key is to transform the metadata into a standardized format. This Oracle PL/SQL block generates comparable DDL:
BEGIN
-- Set transform parameters to exclude schema references
DBMS_METADATA.SET_TRANSFORM_PARAM(
DBMS_METADATA.SESSION_TRANSFORM,
'SQLTERMINATOR', TRUE);
DBMS_METADATA.SET_TRANSFORM_PARAM(
DBMS_METADATA.SESSION_TRANSFORM,
'REF_CONSTRAINTS', FALSE);
DBMS_METADATA.SET_TRANSFORM_PARAM(
DBMS_METADATA.SESSION_TRANSFORM,
'OID', FALSE);
DBMS_METADATA.SET_TRANSFORM_PARAM(
DBMS_METADATA.SESSION_TRANSFORM,
'SEGMENT_ATTRIBUTES', FALSE);
DBMS_METADATA.SET_TRANSFORM_PARAM(
DBMS_METADATA.SESSION_TRANSFORM,
'TABLESPACE', FALSE);
END;
This comprehensive script generates diff-ready output for all critical schema objects:
-- Tables
SELECT
REPLACE(
DBMS_METADATA.GET_DDL('TABLE', table_name),
'"'||SYS_CONTEXT('USERENV','CURRENT_SCHEMA')||'".',
'')
FROM user_tables;
-- Indexes
SELECT
REPLACE(
DBMS_METADATA.GET_DDL('INDEX', index_name),
'"'||SYS_CONTEXT('USERENV','CURRENT_SCHEMA')||'".',
'')
FROM user_indexes;
-- Triggers
SELECT
REPLACE(
DBMS_METADATA.GET_DDL('TRIGGER', trigger_name),
'"'||SYS_CONTEXT('USERENV','CURRENT_SCHEMA')||'".',
'')
FROM user_triggers;
For large schemas, consider these approaches:
- Generate hash values for each object definition
- Compare only the hash values first to identify changed objects
- Use Oracle's Data Dictionary views for quick checks
For frequent comparisons, create a stored procedure that:
CREATE OR REPLACE PROCEDURE compare_schemas AS
v_diff_count NUMBER := 0;
BEGIN
-- Implementation would compare current schema with reference
-- and report differences
DBMS_OUTPUT.PUT_LINE('Schema comparison completed');
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Error: '||SQLERRM);
END;
While scripts work well, dedicated tools like:
- Oracle SQL Developer's Database Diff
- Redgate SQL Compare
- DBComparer
offer more visual comparison features for complex schema differences.