DBMS_DEVELOPER.GET_METADATA in Oracle 23ai(23.7)

 In an Oracle database, to extract object metadata, we can use the DBMS_METADATA package. It provides many useful procedures and functions, such as GET_DDL, GET_DEPENDENT_DDL, and SET_TRANSFORM_PARAM. Additionally, some tools, like SQLcl, provide their own methods for extracting metadata — for example, the DDL command.

Starting with version 23.7, Oracle introduced another method to extract object metadata. In this version, we can use DBMS_DEVELOPER alongside DBMS_METADATA. DBMS_DEVELOPER is user-friendly, and generates output in JSON format.

The DBMS_DEVELOPER package currently supports only TABLE, INDEX, and VIEW, while DBMS_METADATA is much more powerful and supports nearly all object types.

DBMS_DEVELOPER has only one function, called GET_METADATA:

SQL> DESC DBMS_DEVELOPER
FUNCTION GET_METADATA RETURNS JSON
Argument Name Type In/Out Default?
- - - - - - - - - - - - - - - - - - - - -
NAME VARCHAR2 IN
SCHEMA VARCHAR2 IN DEFAULT
OBJECT_TYPE VARCHAR2 IN DEFAULT
LEVEL VARCHAR2 IN DEFAULT
ETAG RAW IN DEFAULT

This function provides output at three levels:
— Basic: Returns only basic information about the object.
— Typical: Returns more detailed information about the object.
— All: Provides all available details about the object.

The output level can be specified using the LEVEL argument.

Usage Examples

The following examples help illustrate how this package works.

Example 1: Retrieving Metadata for a Table (Basic Level)

SQL> select DBMS_DEVELOPER.GET_METADATA (schema =>'VAHID' ,name =>'TB1' ,object_type =>'TABLE' ,level=>'BASIC' ) METADATA;
METADATA
- - - - - - - - - - - - - - - - - - - - - - - - - -
{"objectType":"TABLE","objectInfo":{"name":"TB1","schema":"VAHID","columns":[{"n

As you can see, the output is incomplete. We can use the JSON_SERIALIZE function to display the full output.

Example 2: Using JSON_SERIALIZE to Format Output

SQL> select JSON_SERIALIZE(DBMS_DEVELOPER.GET_METADATA (schema =>'VAHID' ,name =>'TB1' ,object_type =>'TABLE' ,level=>'BASIC' )) METADATA;
METADATA
- - - - - - - - - - - - - - - - - - - - - - -
{"objectType":"TABLE","objectInfo":{"name":"TB1","schema":"VAHID","columns":[{"name":"ID","notNull":true,"dataType":{"type":"NUMBER"}},{"name":"NAME","default":"'Vahid'\n","notNull":true,"dataType":{"type":"VARCHAR2","length":100,"sizeUnits":"BYTE"}},{"name":"LAST_NAME","notNull":false,"dataType":{"type":"VARCHAR2","length":100,"sizeUnits":"BYTE"}}]},"etag":"E8012E8ED81678A603CE5D926BCE3F30"}

Example 3: Pretty-Printing JSON Output

SQL> select JSON_SERIALIZE(DBMS_DEVELOPER.GET_METADATA (schema =>'VAHID' ,name =>'TB1' ,object_type =>'TABLE' ,level=>'BASIC' )pretty ) METADATA;
METADATA
- - - - - - - - - - - - - - - - - - - - -
{
"objectType" : "TABLE",
"objectInfo" :
{
"name" : "TB1",
"schema" : "VAHID",
"columns" :
[
{
"name" : "ID",
"notNull" : true,
"dataType" :
{
"type" : "NUMBER"
}
},
{
"name" : "NAME",
"default" : "'Vahid'\n",
"notNull" : true,
"dataType" :
{
"type" : "VARCHAR2",
"length" : 100,
"sizeUnits" : "BYTE"
}
},
{
"name" : "LAST_NAME",
"notNull" : false,
"dataType" :
{
"type" : "VARCHAR2",
"length" : 100,
"sizeUnits" : "BYTE"
}
}
]
},
"etag" : "E8012E8ED81678A603CE5D926BCE3F30"
}

Example 4: Retrieving Metadata at the ALL Level

SQL> select JSON_SERIALIZE(DBMS_DEVELOPER.GET_METADATA (schema =>'VAHID' ,name =>'TB1' ,object_type =>'TABLE' ,level=>'ALL' )pretty ) METADATA;
METADATA
- - - - - - - - - - - - - - - - - - -
{
"objectType" : "TABLE",
"objectInfo" :
{
"name" : "TB1",
"schema" : "VAHID",
"columns" :
[
{
"name" : "ID",
"notNull" : true,
"dataType" :
{
"type" : "NUMBER"
},
"isPk" : true,
"isUk" : true,
"isFk" : false,
"hiddenColumn" : false
},
{
"name" : "NAME",
"default" : "'Vahid'\n",
"notNull" : true,
"dataType" :
{
"type" : "VARCHAR2",
"length" : 100,
"sizeUnits" : "BYTE"
},
"isPk" : false,
"isUk" : false,
"isFk" : false,
"hiddenColumn" : false
},
{
"name" : "LAST_NAME",
"notNull" : false,
"dataType" :
{
"type" : "VARCHAR2",
"length" : 100,
"sizeUnits" : "BYTE"
},
"isPk" : false,
"isUk" : false,
"isFk" : false,
"hiddenColumn" : false
}
],
"hasBeenAnalyzed" : false,
"indexes" :
[
{
"name" : "SYS_C008430",
"indexType" : "NORMAL",
"uniqueness" : "UNIQUE",
"status" : "VALID",
"hasBeenAnalyzed" : false,
"columns" :
[
{
"name" : "ID"
}
],
"compression" : "DISABLED",
"segmentCreated" : "NO",
"visiblilty" : "VISIBLE",
"toBeDropped" : false
}
],
"constraints" :
[
{
"name" : "SYS_C008429",
"constraintType" : "CHECK - NOT NULL",
"searchCondition" : "\"NAME\" IS NOT NULL",
"columns" :
[
{
"name" : "NAME"
}
],
"status" : "ENABLE",
"deferrable" : false,
"validated" : "VALIDATED",
"sysGeneratedName" : true
},
{
"name" : "SYS_C008430",
"constraintType" : "PRIMARY KEY",
"columns" :
[
{
"name" : "ID"
}
],
"status" : "ENABLE",
"deferrable" : false,
"validated" : "VALIDATED",
"sysGeneratedName" : true
}
],
"segmentCreated" : "NO",
"inMemory" : "DISABLED",
"compression" : "DISABLED"
},
"etag" : "C478C48865258F4DD166DC1319195A4C"
}

Tracking Changes with ETAG

The DBMS_DEVELOPER.GET_METADATA function has another argument called ETAG. This parameter is a unique identifier assigned to the metadata document. If you examine the last output, you will see the ETAG value:

"etag" : "C478C48865258F4DD166DC1319195A4C"

If you run this query again, the ETAG value will remain unchanged unless the metadata has been modified by someone. If the ETAG matches the current version, GET_METADATA will return an empty document.

Example 5: Using ETAG for Change Detection

SQL> select JSON_SERIALIZE(DBMS_DEVELOPER.GET_METADATA (schema =>'VAHID' ,name =>'TB1' ,object_type =>'TABLE' ,level=>'ALL', etag=> 'C478C48865258F4DD166DC1319195A4C' )pretty ) METADATA;
METADATA
- - - - - - - - - - - -
{
}

I will remove a column from TB1 and run the query again:

SQL> alter table vahid.TB1 drop column last_name;
Table altered.

Example 6: Modifying a Table and Checking ETAG

SQL> select JSON_SERIALIZE(DBMS_DEVELOPER.GET_METADATA (schema =>'VAHID' ,name =>'TB1' ,object_type =>'TABLE' ,level=>'ALL', etag=> 'C478C48865258F4DD166DC1319195A4C' )pretty ) METADATA;
METADATA
- - - - - - - - - - - -
{
"objectType" : "TABLE",
"objectInfo" :
{
"name" : "TB1",
"schema" : "VAHID",
….
"compression" : "DISABLED"
},
"etag" : "0BFA3ACD50E33DD69F7E68897C70A7E9"
}

The ETAG in the JSON output will reflect the change, confirming the metadata update.

Conclusion

The DBMS_DEVELOPER package was introduced in Oracle 23.7 and produces metadata in JSON format. It supports only TABLE, INDEX, and VIEW. The GET_METADATA function provides output at BASIC, TYPICAL, and ALL levels. The ETAG parameter helps track changes in object metadata.

Vahid Yousefzadeh
Oracle Database Administrator
✉ vahidusefzadeh@gmail.com

Comments

Popular posts from this blog

Oracle 23ai — Speed up IMPDP Using NOVALIDATE Constraints

Staging Tables in Oracle 23ai

Oracle 23ai — Track Table and Partition Scan Access