Continuemos conociendo un poco más de las cosas nuevas que trae la versión 26.1 de Oracle Application Express.
En esta oportunidad quiero dar un vistazo a las nuevas APIs que forman parte de esta versión, la cual incluye dos nuevas APIs:
- APEX_DB_DICTIONARY
- APEX_INSTANCE_DEBUG
En este artículo, me voy a referir a la primera de ellas y luego lo haré también con la segunda.
APEX_DB_DICTIONARY
Este API, provee descripciones de metadatos de la base de datos amigables con lenguajes LLM (Large Language Model), con la finalidad de facilitar el uso de IA en tareas de interacción con la base de datos, para por ejemplo poder realizar desarrollo de aplicaciones o análisis de datos.
Está compuesta por las siguientes funciones:
GET_METADATA
Básicamente envuelve DBMS_DEVELOPER.GET_METADATA para que pueda ser llamada dentro de una aplicación APEX, conservando los mismos parámetros y pasándolos sin ser alterados, para devolver los valores y pasarlos tal cual a APEX_DB_DICTIONARY.FORMAT_METADATA.
Los parámetros que recibe son:
- p_name, el nombre del objeto
- p_schema, el nombre del esquema de base de datos
- p_object_type, el tipo del objeto que quiere obtener
- p_level, el nivel de detalle a retornar, que puede ser TYPICAL (por defeccto), BASIC o ALL
- p_etag, un identificador único para una versión específica del documento (para poder verificar si hay cambios entre versiones de un documento.
Retorna los metadatos en formato JSON como un objeto JSON para bases de datos 21c o superiores y como CLOB en versiones anteriores.
Veamos un ejemplo en el que queremos recuperar los metadatos de la tabla EMP con nivel de detalle ALL:
|
1 2 3 4 5 6 7 8 |
declare l_json json; begin l_json := apex_db_dictionary.get_metadata( p_name => 'EMP', p_level => 'ALL' ); dbms_output.put_line(json_serialize(l_json)); end; |
Al ejecutarlo, obtenemos el siguiente objeto JSON:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 |
{ "objectType":"TABLE", "objectInfo":{ "schema":"EMOLINA", "columns":[ { "dataType":{ "type":"NUMBER", "precision":4 }, "isPk":true, "hiddenColumn":false, "numDistinct":24, "isUk":true, "reservableColumn":false, "highValue":"C26464", "isFk":false, "encryptedColumn":false, "identityColumn":false, "lowValue":"C105", "density":0.0416666666666667, "notNull":true, "name":"EMPNO", "virtualColumn":false, "avgColLen":4 }, { "dataType":{ "type":"VARCHAR2", "length":15, "sizeUnits":"BYTE" }, "isPk":false, "hiddenColumn":false, "numDistinct":23, "isUk":false, "reservableColumn":false, "highValue":"70657065", "isFk":false, "encryptedColumn":false, "identityColumn":false, "lowValue":"4144414D53", "density":0.043478260869565195, "notNull":false, "name":"ENAME", "virtualColumn":false, "avgColLen":7 }, { "dataType":{ "type":"VARCHAR2", "length":9, "sizeUnits":"BYTE" }, "isPk":false, "hiddenColumn":false, "numDistinct":14, "isUk":false, "reservableColumn":false, "highValue":"70726F6772616D6164", "isFk":false, "encryptedColumn":false, "identityColumn":false, "lowValue":"414E414C49535441", "density":0.0714285714285714, "notNull":false, "name":"JOB", "virtualColumn":false, "avgColLen":9 }, { "dataType":{ "type":"NUMBER", "precision":4 }, "isPk":false, "hiddenColumn":false, "numDistinct":6, "isUk":false, "reservableColumn":false, "highValue":"C25003", "isFk":true, "encryptedColumn":false, "identityColumn":false, "lowValue":"C24C43", "density":0.166666666666667, "notNull":false, "name":"MGR", "virtualColumn":false, "avgColLen":4 }, { "dataType":{ "type":"DATE" }, "isPk":false, "hiddenColumn":false, "numDistinct":22, "isUk":false, "reservableColumn":false, "highValue":"78750B1B010101", "isFk":false, "encryptedColumn":false, "identityColumn":false, "lowValue":"77B40C11010101", "density":0.045454545454545504, "notNull":false, "name":"HIREDATE", "virtualColumn":false, "avgColLen":8 }, { "dataType":{ "type":"NUMBER", "precision":7, "scale":2 }, "isPk":false, "hiddenColumn":false, "numDistinct":18, "isUk":false, "reservableColumn":false, "highValue":"C233", "isFk":false, "encryptedColumn":false, "identityColumn":false, "lowValue":"C206", "density":0.0555555555555556, "notNull":false, "name":"SAL", "virtualColumn":false, "avgColLen":4 }, { "dataType":{ "type":"NUMBER", "precision":7, "scale":2 }, "isPk":false, "hiddenColumn":false, "numDistinct":7, "isUk":false, "reservableColumn":false, "highValue":"C20F", "isFk":false, "encryptedColumn":false, "identityColumn":false, "lowValue":"80", "density":0.142857142857143, "notNull":false, "name":"COMM", "virtualColumn":false, "avgColLen":2 }, { "dataType":{ "type":"NUMBER", "precision":2 }, "isPk":false, "hiddenColumn":false, "numDistinct":4, "isUk":false, "reservableColumn":false, "highValue":"C15A", "isFk":true, "encryptedColumn":false, "identityColumn":false, "lowValue":"C10B", "density":0.026315789473684202, "notNull":false, "name":"DEPTNO", "virtualColumn":false, "avgColLen":3 } ], "inMemory":"DISABLED", "numRows":24, "dependencies":"DISABLED", "external":"NO", "constraints":[ { "name":"SYS_C003093967", "constraintType":"CHECK - NOT NULL", "searchCondition":"\"EMPNO\" IS NOT NULL", "columns":[ { "name":"EMPNO" } ], "status":"ENABLED", "deferrable":false, "validated":"VALIDATED", "sysGeneratedName":true }, { "name":"SYS_C003093968", "constraintType":"PRIMARY KEY", "columns":[ { "name":"EMPNO" } ], "status":"ENABLED", "deferrable":false, "validated":"VALIDATED", "sysGeneratedName":true }, { "Action":"RESTRICT", "referencedConstraintName":"SYS_C003093968", "constraintType":"REFERENTIAL INTEGRITY", "columns":[ { "name":"MGR" } ], "referencedColumns":[ { "name":"EMPNO" } ], "sysGeneratedName":true, "deferrable":false, "referencedOwner":"EMOLINA", "referencedTable":"EMP", "name":"SYS_C003093969", "status":"ENABLED", "validated":"VALIDATED" }, { "Action":"RESTRICT", "referencedConstraintName":"SYS_C003093966", "constraintType":"REFERENTIAL INTEGRITY", "columns":[ { "name":"DEPTNO" } ], "referencedColumns":[ { "name":"DEPTNO" } ], "sysGeneratedName":true, "deferrable":false, "referencedOwner":"EMOLINA", "referencedTable":"DEPT", "name":"SYS_C003093970", "status":"ENABLED", "validated":"VALIDATED" } ], "lastAnalyzed":"2023-05-08T17:04:29", "sampleSize":24, "segmentCreated":"YES", "indexes":[ { "indexType":"NORMAL", "partitioned":false, "columns":[ { "name":"EMPNO" } ], "uniqueness":"UNIQUE", "numRows":24, "toBeDropped":false, "lastAnalyzed":"2023-05-08T17:04:29", "sampleSize":24, "segmentCreated":"YES", "distinctKeys":24, "visibility":"VISIBLE", "name":"SYS_C003093968", "status":"VALID", "compression":"DISABLED" } ], "avgRowLen":38, "name":"EMP", "compression":"DISABLED", "temporary":"NO" }, "etag":"8BF4F6DF554EAD3ED35170888821D46C" } |
GET_PRIMARY_KEY_COLUMNS
Esta función retorna una lista delimitada por comas “,” de los nombres de las columnas en la llave primaria de una tabla. Si la tabla no tiene una llave primaria, entonces retorna un valor nulo.
La función recibe los siguientes parámetros:
- p_table, el nombre de la tabla
- p_owner, el nombre del esquema dueño de la tabla (opcional)
- p_delimiter, el delimitador de la lista, que como lo expliqué si no se proporciona utiliza “,”
Sigamos utilizando la tabla EMP y veamos como obtenemos las columnas de llave primaria de dicha tabla:
|
1 2 3 4 5 6 7 8 |
declare l_pk_columns varchar2(32767); begin l_pk_columns := apex_db_dictionary.get_primary_key_columns( p_table => 'EMP', p_delimiter => ':' ); dbms_output.put_line(l_pk_columns); end; |
Si lo ejecutamos, el código va a retornar simplemente:
EMPNO
Que corresponde al nombre de la columna definida como llave primaria de la tabla EMP.
GET_TABLE_INFO
Esta función tiene dos versiones o variantes diferentes, las cuales retornan metadatos formateados para una o más tablas o vistas, con la única diferencia entre ambas en la forma en que se proporciona la lista de tablas o vistas de las cuales se quiere recuperar los metadatos.
En la primera versión, pasamos los nombres como una lista de valores separados por coma, mientras que en la segunda, los pasamos como un arreglo con los nombres de las tablas o vistas.
Los parámetros que aceptan estas funciones son:
- p_table_names / p_table_array, la lista de tablas o vistas a procesar
- p_include_constraints, mostrar u ocultar la sección de constraints – TRUE por defecto
- p_include_indexes, mostrar u ocultar sección de indices – FALSE por defecto
- p_include_comments, mostrar u ocultar comentarios de tabla/columnas -TRUE por defecto
- p_include_annotations, mostrar u ocultar sección de anotaciones – TRUE por defecto
- p_include_domains, mostrar u ocultar sección de metadatos de dominios SQL – TRUE por defecto
- p_include_virtual_columns, mostrar u ocultar en la salida columnas virtuales – FALSE por defecto
- p_format, formato de salida c_markdown o c_plain, el primero de ellos por defecto
El objeto retornado es un CLOB con los metadatos solicitados.
Veamos ahora un ejemplo en el que vamos a utilizar la primera de las versiones para obtener los metadatos de las tablas EMP y DEPT:
|
1 2 3 4 5 6 7 |
declare l_text clob; begin l_text := apex_db_dictionary.get_table_info( p_table_names => 'EMP, DEPT' ); dbms_output.put_line(l_text); end; |
Al ejecutarlo, vamos a obtener lo siguiente:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
# Table: EMP ## Columns: - EMPNO - NUMBER(4) NOT NULL [pk] - ENAME - VARCHAR2(15) - JOB - VARCHAR2(9) - MGR - NUMBER(4) [fk] - HIREDATE - DATE - SAL - NUMBER(7,2) - COMM - NUMBER(7,2) - DEPTNO - NUMBER(2) [fk] ## Column Comments: - EMPNO - mployee number - ENAME - mployee lastname ## Constraints: - CONSTRAINT - PRIMARY KEY (EMPNO) - CONSTRAINT - FOREIGN KEY (MGR) -> EMP(EMPNO) - CONSTRAINT - FOREIGN KEY (DEPTNO) -> DEPT(DEPTNO) # Table: DEPT ## Columns: - DEPTNO - NUMBER(2) NOT NULL [pk] - DNAME - VARCHAR2(14) - LOC - VARCHAR2(13) ## Constraints: - CONSTRAINT - PRIMARY KEY (DEPTNO) |
GET_TABLE_INFO_REGEX
Esta función a las funciones GET_TABLE_INFO, la única diferencia es que devuelve la información de las tablas o vistas que concuerdan con la expresión regular que se le proporciona.
Los parámetros que aceptan estas funciones son:
- p_regex, expresión regular usada para buscar las tablas o vistas
- p_owner, nombre del esquema dueño de las tablas o vistas,
- p_object_type, tipo de objetos a recuperar, puede ser TABLE o VIEW, si no se proporciona devuelve ambos tipos de objeto
- p_include_constraints, mostrar u ocultar la sección de constraints – TRUE por defecto
- p_include_indexes, mostrar u ocultar sección de indices – FALSE por defecto
- p_include_comments, mostrar u ocultar comentarios de tabla/columnas -TRUE por defecto
- p_include_annotations, mostrar u ocultar sección de anotaciones – TRUE por defecto
- p_include_domains, mostrar u ocultar sección de metadatos de dominios SQL – TRUE por defecto
- p_include_virtual_columns, mostrar u ocultar en la salida columnas virtuales – FALSE por defecto
- p_format, formato de salida c_markdown o c_plain, el primero de ellos por defecto
El objeto retornado es un CLOB con los metadatos solicitados.
Veamos ahora un ejemplo en el que vamos a solicitar la información de tablas o vistas que contengan en su nombre ORDER o TAGS:
|
1 2 3 4 5 6 7 |
declare l_text clob; begin l_text := apex_db_dictionary.get_table_info_regex( p_regex => 'ORDER|TAGS' ); dbms_output.put_line(l_text); end; |
El resultado de ejecutar este código devuelve en mi ambiente de pruebas:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# Table: APEX$_WS_TAGS ## Columns: - ID - NUMBER NOT NULL [pk] - WS_APP_ID - NUMBER NOT NULL - DATA_GRID_ID - NUMBER - ROW_ID - NUMBER [fk] - WEBPAGE_ID - NUMBER - COMPONENT_LEVEL - VARCHAR2(30) - TAG - VARCHAR2(4000) - CREATED_ON - DATE NOT NULL - CREATED_BY - VARCHAR2(255) NOT NULL - UPDATED_ON - DATE - UPDATED_BY - VARCHAR2(255) ## Constraints: - APEX$_WS_TAGS_CL_CK - CHECK (COMPONENT_LEVEL) - APEX$_WS_TAGS_PK - PRIMARY KEY (ID) - APEX$_WS_TAGS_FK - FOREIGN KEY (ROW_ID) -> APEX$_WS_ROWS(ID) # Table: DEMO_ORDERS ## Columns: - ORDER_ID - NUMBER NOT NULL [pk] - CUSTOMER_ID - NUMBER NOT NULL [fk] - ORDER_TOTAL - NUMBER(8,2) - ORDER_TIMESTAMP - TIMESTAMP - USER_NAME - VARCHAR2(100) - TAGS - VARCHAR2(4000) ## Constraints: - DEMO_ORDER_TOTAL_MIN - CHECK (ORDER_TOTAL) - DEMO_ORDER_PK - PRIMARY KEY (ORDER_ID) - DEMO_ORDERS_CUSTOMER_ID_FK - FOREIGN KEY (CUSTOMER_ID) -> DEMO_CUSTOMERS(CUSTOMER_ID) # Table: DEMO_ORDER_ITEMS ## Columns: - ORDER_ITEM_ID - NUMBER(3) NOT NULL [pk] - ORDER_ID - NUMBER NOT NULL [uk] [fk] - PRODUCT_ID - NUMBER NOT NULL [uk] [fk] - UNIT_PRICE - NUMBER(8,2) NOT NULL - QUANTITY - NUMBER(8) NOT NULL ## Constraints: - DEMO_ORDER_ITEMS_PK - PRIMARY KEY (ORDER_ITEM_ID) - DEMO_ORDER_ITEMS_UK - UNIQUE (ORDER_ID, PRODUCT_ID) - DEMO_ORDER_ITEMS_FK - FOREIGN KEY (ORDER_ID) -> DEMO_ORDERS(ORDER_ID) - DEMO_ORDER_ITEMS_PRODUCT_ID_FK - FOREIGN KEY (PRODUCT_ID) -> DEMO_PRODUCT_INFO(PRODUCT_ID) # Table: DEMO_TAGS ## Columns: - ID - NUMBER NOT NULL [pk] - TAG - VARCHAR2(255) NOT NULL - CONTENT_ID - NUMBER - CONTENT_TYPE - VARCHAR2(30) - CREATED - TIMESTAMP - CREATED_BY - VARCHAR2(255) - UPDATED - TIMESTAMP - UPDATED_BY - VARCHAR2(255) ## Constraints: - DEMO_TAGS_CK - CHECK (CONTENT_TYPE) - CONSTRAINT - PRIMARY KEY (ID) # Table: DEMO_TAGS_SUM ## Columns: - TAG - VARCHAR2(255) NOT NULL [pk] - TAG_COUNT - NUMBER ## Constraints: - DEMO_TAGS_SUM_PK - PRIMARY KEY (TAG) # Table: DEMO_TAGS_TYPE_SUM ## Columns: - TAG - VARCHAR2(255) NOT NULL [pk] - CONTENT_TYPE - VARCHAR2(30) NOT NULL [pk] - TAG_COUNT - NUMBER ## Constraints: - DEMO_TAGS_TYPE_SUM_PK - PRIMARY KEY (TAG, CONTENT_TYPE) |
GET_TABLES_ARRAY
Esta función devuelve una lista de nombres de tablas y/o vistas que coinciden con el criterio de búsqueda proporcionado como una expresión regular. Si el parámetro p_regex resulta nulo después de aplicar un “trim”, entonces se retorna un arreglo vacío, de lo contrario se devuelve un arreglo de nombres cualificados en el formato “owner.name”.
Los parámetros utilizados por esta función son:
- p_regex, expresión regular para los nombres de objetos
- p_owner, nombre del esquema dueño de los objetos
- p_object_type, tipo de objetos a considerar: TABLE o VIEW, si no se proporciono retorna ambos tipos
En el ejemplo a continuación, vamos a recuperar los nombres de las tablas que inician con “EBA_”:
|
1 2 3 4 5 6 7 8 9 10 |
declare l_tables apex_t_varchar2; begin l_tables := apex_db_dictionary.get_tables_array( p_regex => '^EBA_' ); for i in 1 .. l_tables.count loop dbms_output.put_line(l_tables(i)); end loop; end; |
Si ejecutamos el código, en mi ambiente de pruebas, recibo el siguinte resultado:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
"EMOLINA"."EBA_DEMO_CAL_MYSESSIONS" "EMOLINA"."EBA_DEMO_CAL_PROJECTS" "EMOLINA"."EBA_DEMO_CAL_SESSIONS" "EMOLINA"."EBA_DEMO_IR_DEPT" "EMOLINA"."EBA_DEMO_IR_EMP" "EMOLINA"."EBA_DEMO_IR_PROJECTS" "EMOLINA"."EBA_PROJECTS" "EMOLINA"."EBA_PROJECTS_COMPLETED_V" "EMOLINA"."EBA_PROJECTS_V" "EMOLINA"."EBA_PROJECT_COMMENTS" "EMOLINA"."EBA_PROJECT_MILESTONES" "EMOLINA"."EBA_PROJECT_STATUS" "EMOLINA"."EBA_PROJECT_TASKS" "EMOLINA"."EBA_PROJECT_TASK_LINKS" "EMOLINA"."EBA_PROJECT_TASK_TODOS" "EMOLINA"."EBA_UT_CHART_PROJECTS" "EMOLINA"."EBA_UT_CHART_TASKS" |
GET_TABLES_JSON
Esta función es similar a la anterior, solo que en este caso retorna un objeto JSON que contiene dueño, nombre de objeto y tipo de objeto que coinciden con el criterio de búsqueda proporcionado como una expresión regular y, adicionalmente también podría incluir información de comentarios de tabla y columnas, así como de las anotaciones hechas en tablas o columnas de tablas, en caso de que existan. Si el parámetro p_regex resulta nulo después de aplicar un “trim”, entonces se retorna un arreglo vacío, de lo contrario se devuelve un arreglo de nombres cualificados en el formato “owner.name”.
Los parámetros utilizados por esta función son:
- p_regex, expresión regular para los nombres de objetos
- p_owner, nombre del esquema dueño de los objetos
- p_object_type, tipo de objetos a considerar: TABLE o VIEW, si no se proporciono retorna ambos tipos
- p_include_comments, incluir u ocultar comentarios de tablas y vistas – TRUE por defecto
- p_include_annotations, incluir u ocultar anotaciones de tablas y viastas – TRUE por defecto
En el ejemplo a continuación, al igual que en el anterior, vamos a recuperar los nombres de las tablas que inician con “EBA_”:
|
1 2 3 4 5 6 7 |
declare l_json json; begin l_json := apex_db_dictionary.get_tables_json( p_regex => '^EBA_' ); dbms_output.put_line(json_serialize(l_json)); end; |
El resultado, luego de pasarlo por un formateador de JSON, luce así:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
[ { "owner":"EMOLINA", "name":"EBA_DEMO_CAL_MYSESSIONS", "type":"TABLE" }, { "owner":"EMOLINA", "name":"EBA_DEMO_CAL_PROJECTS", "type":"TABLE" }, { "owner":"EMOLINA", "name":"EBA_DEMO_CAL_SESSIONS", "type":"TABLE" }, { "owner":"EMOLINA", "name":"EBA_DEMO_IR_DEPT", "type":"TABLE" }, { "owner":"EMOLINA", "name":"EBA_DEMO_IR_EMP", "type":"TABLE" }, { "owner":"EMOLINA", "name":"EBA_DEMO_IR_PROJECTS", "type":"TABLE" }, { "owner":"EMOLINA", "name":"EBA_PROJECTS", "type":"TABLE" }, { "owner":"EMOLINA", "name":"EBA_PROJECT_COMMENTS", "type":"TABLE" }, { "owner":"EMOLINA", "name":"EBA_PROJECT_MILESTONES", "type":"TABLE" }, { "owner":"EMOLINA", "name":"EBA_PROJECT_STATUS", "type":"TABLE" }, { "owner":"EMOLINA", "name":"EBA_PROJECT_TASKS", "type":"TABLE" }, { "owner":"EMOLINA", "name":"EBA_PROJECT_TASK_LINKS", "type":"TABLE" }, { "owner":"EMOLINA", "name":"EBA_PROJECT_TASK_TODOS", "type":"TABLE" }, { "owner":"EMOLINA", "name":"EBA_UT_CHART_PROJECTS", "type":"TABLE" }, { "owner":"EMOLINA", "name":"EBA_UT_CHART_TASKS", "type":"TABLE" }, { "owner":"EMOLINA", "name":"EBA_PROJECTS_COMPLETED_V", "type":"VIEW" }, { "owner":"EMOLINA", "name":"EBA_PROJECTS_V", "type":"VIEW" } ] |
GET_TABLES_SUMMARY
Esta función retorna un resumen de las tablas y vistas en un esquema de base de datos que coinciden con la expresión regular de búsqueda proporcionada, el resultado lo genera ya sea en texto plano o en formato markdown, dentro de un objeto CLOB.
Los parámetros que utiliz la función son:
- p_regex, expresión regular de búsqueda
- p_owner, nombre del esquema de base de datos dueño de los objetos
- p_object_type, tipo de objetos: TABLE o VIEW, si no se proporciona retorna ambos tipos
- p_include_comments, incluir u ocultar comentarios – TRUE por defecto
- p_include_annotations, incluir u ocultar anotaciones – TRUE por defecto
- p_format, formato de salida: c_markdown (por defecto) o c_plain
En el ejemplo para esta función, vamos a conservar la misma premisa que en los ejemplos anteriores y vamos a recuperar la infomación de tablas y vistas que empiezaen con “EBA_”:
|
1 2 3 4 5 6 7 |
declare l_summary clob; begin l_summary := apex_db_dictionary.get_tables_summary( p_regex => '^EBA_' ); dbms_output.put_line(l_summary); end; |
Y a continuación el resultado:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
# EMOLINA Tables and Views (/^EBA_/) ## Tables: - EBA_DEMO_CAL_MYSESSIONS - EBA_DEMO_CAL_PROJECTS - EBA_DEMO_CAL_SESSIONS - EBA_DEMO_IR_DEPT - EBA_DEMO_IR_EMP - EBA_DEMO_IR_PROJECTS - EBA_PROJECTS - EBA_PROJECT_COMMENTS - EBA_PROJECT_MILESTONES - EBA_PROJECT_STATUS - EBA_PROJECT_TASKS - EBA_PROJECT_TASK_LINKS - EBA_PROJECT_TASK_TODOS - EBA_UT_CHART_PROJECTS - EBA_UT_CHART_TASKS ## Views: - EBA_PROJECTS_COMPLETED_V - EBA_PROJECTS_V |
FORMAT_METADATA
Convierte la salida JSON de DBMS_DEVELOPER.GET_METADATA a un formato de texto legible por humanos y LLM.
Utiliza los parámetros:
- p_json, objeto JSON a formatear
- p_include_constraints, mostrar u ocultar la sección de constraints – TRUE por defecto
- p_include_indexes, mostrar u ocultar la sección de índices – FALSE por defecto
- p_include_comments, incluir u ocultar comentarios – TRUE por defecto
- p_include_annotations, incluir u ocultar anotaciones – TRUE por defecto
- p_include_domains, mostrar u ocultar la sección de metadatos de dominios SQL – TRUE por defecto
- p_include_virtual_columns, mostrar u ocultar columnas virtuales en la salida – FALSE por defecto
- p_format, formato de salida: c_markdown (por defecto) o c_plain
Al inicio de esta sección, mencioné que la función GET_METADATA es un envoltorio para DBMS_DEVELOPER.GET_METADATA, de manera que en este ejemplo vamos a tomar la salida de GET_METADATA y la vamos a pasar a esta función para ver el resultado:
|
1 2 3 4 5 6 7 8 9 10 |
declare l_json json; l_text clob; begin l_json := apex_db_dictionary.get_metadata( p_name => 'EMP', p_level => 'ALL' ); l_text := apex_db_dictionary.format_metadata(l_json); dbms_output.put_line(l_text); end; |
El resultado obtenido es:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
# Table: EMP ## Columns: - EMPNO - NUMBER(4) NOT NULL [pk] - ENAME - VARCHAR2(15) - JOB - VARCHAR2(9) - MGR - NUMBER(4) [fk] - HIREDATE - DATE - SAL - NUMBER(7,2) - COMM - NUMBER(7,2) - DEPTNO - NUMBER(2) [fk] ## Column Comments: - EMPNO - mployee number - ENAME - mployee lastname ## Constraints: - CONSTRAINT - PRIMARY KEY (EMPNO) - CONSTRAINT - FOREIGN KEY (MGR) -> EMP(EMPNO) - CONSTRAINT - FOREIGN KEY (DEPTNO) -> DEPT(DEPTNO) |
Como puede ver, la función a tomado el objeto JSON y lo muestra como texto legible de manera sencilla por cualquier persona o LLM.
Esta función tiene una segunda versión para quienes manejan bases de datos 19c, de manera que la puedan utilizar. La única diferencia estriva en que en lugar de proporcionar un objeto de tipo JSON a la misma, se proporciona un objeto CLOB con formato JSON.
IS_SUPPORTED
Esta función verifica si su base de datos puede utilizar el paquete DBMS_DEVELOPER, en el cual está basada la API de APEX 26.1 APEX_DB_DICTIONARY y retorna un valor boleano.
No utiliza ningún parámetro.
A continuación un ejemplo de su uso, en el que simplemente muestro un mensaje que indica si DBMS_DEVELOPER es soportado por la base de datos:
|
1 2 3 4 5 6 7 8 9 10 |
declare l_supported boolean; begin l_supported := apex_db_dictionary.is_supported; if l_supported then dbms_output.put_line('Su base de datos puede utilizar DBMS_DEVELOPER'); else dbms_output.put_line('Su base de datos MO puede utilizar DBMS_DEVELOPER'); end if; end; |
El resultado obtenido es:
|
1 |
Su base de datos puede utilizar DBMS_DEVELOPER |
Pata conocer más sobre la API APEX_DB_DICTIONARY, visite el enlace














