Thursday, November 05, 2026

DBMS_DEVELOPER.GET_METADATA ignores GRANT SELECT ANY TABLE ON SCHEMA XYZ

I hoped that on Oracle 26ai I could finally leverage schema level privileges and avoid the hassle of granting SELECT explicitly table by table.

grant select any table on schema PB_040000 to TT_020000;

And it works well with SELECT queries and with DESCRIBE too.

Image courtesy of Google Gemini

It works also on tables created after granting the privilege.

But, unfortunately, it turns out that DBMS_DEVELOPER.GET_METADATA ignores the schema level privilege:

--connect as TT_020000

set serveroutput on
begin
dbms_output.put_line(
json_serialize(
dbms_developer.get_metadata(
name => 'ORDERS',
schema => 'PB_040000',
object_type => 'TABLE',
level => 'BASIC'
)
PRETTY
)
);
end;
/

begin
*
ERROR at line 1:
ORA-03408: Object not found : PB_040000.ORDERS
ORA-06512: at "SYS.DBMS_DEVELOPER", line 17
ORA-06512: at "SYS.DBMS_DEVELOPER", line 57
ORA-06512: at line 2


https://docs.oracle.com/error-help/db/ora-03408/


More Details :
https://docs.oracle.com/error-help/db/ora-03408/
https://docs.oracle.com/error-help/db/ora-06512/  

Whether the security model of DBMS_DEVELOPER should change in the future and become compatible with schema level privileges is a valid question in my humble opinion.

Monday, October 26, 2026

A Picture Is Worth A Thousand Words: Dashboards To The Rescue

Building an application in the age of AI assisted development is only half the battle.

With an APEX application hosted on OCI, monitoring resource consumption is vital, because with the free tier you cannot exceed certain volumes of requests, whether they are REST requests or emails or notifications.

A well-crafted dashboard, beyond just eye-catching aesthetics, can help you spot problems that might otherwise go unnoticed until the application runs out of resources and stops working. 

The position of the big blue circle shows there is something wrong with the embedding calls 

Spotting anomalies at a glance:

A prime example of a dashboard's utility is how it highlights hidden inefficiencies and runaway processes.
In the API requests visualization, in the lower left portion of the image, a massive blue circle was dominating the chart, immediately drawing my attention.

  • The big blue bubble instantly signals an anomaly in the system's traffic pattern. 
  • The position of its centre on the Y axis compared to the position of other types of requests over the week reveals that the application is currently executing a disproportionate number of embedding requests to the LLM. 
  • Looking at the chart I could immediately start investigating the rogue document processing procedure.

SELECT 
  -- Chronological X: 6 = 6 days ago, 0 = Today
  to_char(w.request_date,'Day') as dy,
  (trunc(w.request_date) - trunc(sysdate)) as x_value,
  nvl(regexp_substr(w.url,'(http(s)?:/)(/([^/]+))+',1,1,'c',4), 'UNKNOWN') as series,
  count(*)                                     as requests,    -- Y-axis
  sum(elapsed_sec)                             as elapsed,     -- Bubble radius
  to_char(w.request_date,'Day') || '
Requests: ' || count(*) || '
Time: ' || sum(elapsed_sec) as custom_tooltip
FROM apex_webservice_log w
WHERE w.request_date >= trunc(sysdate) - 6 and w.request_date < trunc(sysdate) + 1
GROUP BY to_char(w.request_date,'Day'),
         (trunc(w.request_date) - trunc(sysdate)), 
         nvl(regexp_substr(w.url,'(http(s)?:/)(/([^/]+))+',1,1,'c',4), 'UNKNOWN')
ORDER BY x_value desc, series;

Dashboards can bridge the gap between hundreds of log entries in an APEX internal view and the need to extract and present the significant information in an efficient and concise way. 

Last but not least, AI can suggest the critical resources to monitor and how to best represent the information with a chart if you are short of ideas.

Monday, October 19, 2026

Defending Your PL/SQL Code: Why Anchoring with %TYPE Saves the Day

You are loading an associative array and you are getting the following error: 

ORA-06502: PL/SQL: value or conversion error: 
associative array key violates its type constraints
 

image created by Google Gemini

When I asked Gemini for this error message it said it had to do with a null value in the key but this is false, if the key value is null you'll get a different error message:

ORA-06502: PL/SQL: value or conversion error: NULL index table key value 

And there is also another interesting fact, if you explicitly assign an array element indexed by varchar2(n), in this fashion:

g_arr('') := 'something';

no error whatsoever, the whole array is wiped out, as if you executed g_arr.delete, and it's not clear to me if this is a bug or expected behavior.

So let's see the real reason for "associative array key violates its type constraints":

Create table config (config_key varchar2(50), config_value varchar2(500));

insert into config values('some_key', 'some value');
insert into config values('some_key_with_a_long_name', 'some other value');

declare
  type t_associative_array is table of varchar2(500) index by varchar2(10);
  g_arr      t_associative_array;
  k          varchar2(50);
begin
    FOR rec in (select config_key, config_value from config)
    LOOP
        g_arr(rec.config_key) := rec.config_value;
    END LOOP;

    k := g_arr.first;
    WHILE k IS NOT NULL LOOP
    DBMS_Output.PUT_LINE ('''' || k || ''':''' || g_arr(k)||'''');
    k := g_arr.NEXT(k);
  END LOOP;
 
end;
/

And bum!

ORA-06502: PL/SQL: value or conversion error: 
associative array key violates its type constraints
 

The problem is that you declared the associative array key to be INDEX BY VARCHAR2(10), but the value coming from table is longer.

This type of problems can easily happen when you add new values over time whose length can be longer than original ones and you were a bit lazy when you wrote the code, declaring some variables with explicit data types to save some typing.

To avoid surprises you can rewrite the script as follows:

declare
  type t_associative_array is table of config.config_value%type
index by config.config_key%type; g_arr t_associative_array; k config.config_key%type; begin FOR rec in (select config_key, config_value from config) LOOP g_arr(rec.config_key) := rec.config_value; END LOOP; k := g_arr.first; WHILE k IS NOT NULL LOOP DBMS_Output.PUT_LINE ('''' || k || ''':''' || g_arr(k)||''''); k := g_arr.NEXT(k); END LOOP; end;
/

This time it will output the values without errors.

'some_key':'some value'
'some_key_with_a_long_name':'some other value'

Statement processed.

Is this error specific for associative array key ?
Yes it is, if the problem is in the length of the value, you will get this error instead:

ORA-06502: PL/SQL: value or conversion error: character string buffer too small

This distinction is good because it pinpoints the root cause of the problem.

Last but not least: watch out for the column and variable length semantics!

If you store the keys containing some variable length characters and you defined the associative array using byte semantics using explicit data types, you could incur in the same errors and be confused as the length of the key or the value seem to be within the valid range.

The best solution, and best practice by the way, is to define the array and the variables as shown above, referring to the table columns definition.

yes you can!

Two great ways to help us out with a minimal effort. Click on the Google Plus +1 button above or...
We appreciate your support!

latest articles