Thursday, November 27, 2025

Creating and Using Table Hyperlink Groups in Oracle Autonomous Database

Table Hyperlinks in Oracle Autonomous Database provide a secure and convenient way to expose database objects and SQL query results through pre-authenticated URLs.
 
A recent enhancement extends this capability even further—Table Hyperlink Groups, which allow a single URL to represent multiple hyperlinks, each pointing to a table, view, or SQL query.
 
A Hyperlink Group allows you to bundle several table hyperlinks into a single group URL.
This is useful when: 
  • You want a single API endpoint that exposes multiple datasets
  • You want to simplify integration for downstream systems
  • You want to centralize access control under one pre-authenticated URL
  • You want to organize multiple SQL queries or objects logically
 
Below is a conceptual representation:



 
In this example, we will see how to create a Table Hyperlink Group using two data sources — one defined by a SQL query and the other referencing a table.
 
demo-user@ATP19C> declare
  2     l_status long;
  3  begin
  4     dbms_data_access.create_url(
  5             sqls => '[
  6                               {
  7                                     "name": "Employees table",
  8                                     "description": "Employees details",
  9                                     "sql_statement": " select empno,ename,hiredate,job,deptno from emp "
 10                               },
 11                               {
 12                                     "name": "Department table",
 13                                     "description": "Department details",
 14                                     "schema_name": "DEMO_USER",
 15                                     "schema_object_name": "DEPT"
 16                               }
 17                             ]'
 18             , result => l_status );
 19     dbms_output.put_line( l_status );
 20  end;
 21  /
{
  "status" : "SUCCESS",
  "id" : "JxfkVbJGWKYbD83nyC1wgcGTEuO2-6lzJDgN68V5Z7_Xf4OUTERg7CeUmXnU0RQh",
  "preauth_url" : "https://dataaccess.adb.us-ashburn-1.oraclecloudapps.com/adb/p/GW147LdUM4iIPKAsgNe2NIoByKCCGThJN4RKlrxHkcv7x_erMFkD8GQsgjprD64on7lQML_f2v8/data",
  "member_ids" :
  [
    "T_mxypj7jytHDoW5Li--q0Agxk_TKL3s2SZ46bJ0R6rMrDFa-X8lTLV5KjHsnEUk",
    "9I6oXda2SKvyDfTu8cCsr8c9T_BOUqIHT0kz4qgvWWAHG3dWYfoWmrDTdriNHp0J"
  ],
  "expiration_ts" : "2026-02-23T16:33:47.309Z"
}
 
PL/SQL procedure successfully completed.
 
demo-user@ATP19C>
 
Calling the group URL returns information about all member hyperlinks:
 
$ curl https://dataaccess.adb.us-ashburn-1.oraclecloudapps.com/adb/p/GW147LdUM4iIPKAsgNe2NIoByKCCGThJN4RKlrxHkcv7x_erMFkD8GQsgjprD64on7lQML_f2v8/data
 
{
  "member_urls": [
    {
      "id": "T_mxypj7jytHDoW5Li--q0Agxk_TKL3s2SZ46bJ0R6rMrDFa-X8lTLV5KjHsnEUk",
      "name": "Employees table",
      "description": "Employees details"
    },
    {
      "id": "9I6oXda2SKvyDfTu8cCsr8c9T_BOUqIHT0kz4qgvWWAHG3dWYfoWmrDTdriNHp0J",
      "name": "Department table",
      "description": "Department details"
    }
  ]
}
 
 
To query data from a specific member in the group, supply its member_id:
 
$ curl https://dataaccess.adb.us-ashburn-1.oraclecloudapps.com/adb/p/GW147LdUM4iIPKAsgNe2NIoByKCCGThJN4RKlrxHkcv7x_erMFkD8GQsgjprD64on7lQML_f2v8/data?member_id=9I6oXda2SKvyDfTu8cCsr8c9T_BOUqIHT0kz4qgvWWAHG3dWYfoWmrDTdriNHp0J
 
{
  "items": [
    {
      "DEPTNO": 10,
      "DNAME": "ACCOUNTING",
      "LOC": "NEW YORK"
    },
    {
      "DEPTNO": 20,
      "DNAME": "RESEARCH",
      "LOC": "DALLAS"
    },
    {
      "DEPTNO": 30,
      "DNAME": "SALES",
      "LOC": "CHICAGO"
    },
    {
      "DEPTNO": 40,
      "DNAME": "OPERATIONS",
      "LOC": "BOSTON"
    }
  ],
  "hasMore": false,
  "limit": 1000,
  "offset": 0,
  "count": 4,
  "links": [
    {
      "rel": "self",
      "href": "https://dataaccess.adb.us-ashburn-1.oraclecloudapps.com/adb/p/GW147LdUM4iIPKAsgNe2NIoByKCCGThJN4RKlrxHkcv7x_erMFkD8GQsgjprD64on7lQML_f2v8/data?member_id=9I6oXda2SKvyDfTu8cCsr8c9T_BOUqIHT0kz4qgvWWAHG3dWYfoWmrDTdriNHp0J"
    }
  ]
}
 
You can list all active hyperlinks — including groups — using json_table on dbms_data_access.list_active_urls:
 
demo-user@ATP19C> select *
  2  from
  3      json_table ( dbms_data_access.list_active_urls, '$[*]'
  4          columns (
  5              id
  6          , created_by
  7          , access_count
  8          , created path '$.created.timestamp()'
  9         , sql_statement
 10         , is_group_url
 11         )
 12*    ) ;
 
ID                                                                  CREATED_BY    ACCESS_COUNT    CREATED                            SQL_STATEMENT                                                       IS_GROUP_URL
___________________________________________________________________ _____________ _______________ __________________________________ ___________________________________________________________________ _______________
4PVOG8xtDt7CXzyhcKDcbAkW2rnXAWrzMAGt9W7D5IAOQwjPkrZbSGwRpsR7UNkP    DEMO_USER     1               15-NOV-25 03.54.44.291000000 PM     select * from emp where hiredate = :b1
JxfkVbJGWKYbD83nyC1wgcGTEuO2-6lzJDgN68V5Z7_Xf4OUTERg7CeUmXnU0RQh    DEMO_USER     4               25-NOV-25 04.33.47.333000000 PM                                                                        true
vzCL8zVM2Vj5Z0jGqhIb-56J7SlRvvnnqdelPVmUhOcRz2NbgG4BMVnGqY5dxCzU    DEMO_USER     4               16-NOV-25 03.57.59.390000000 PM     select * from emp where deptno = 10
v09slcWFCCHUgaH3XEEqqwMQClpSHabYebpYPaFp6Z3vsdnT6An8CZeCmfJv0-Oy    DEMO_USER     5               15-NOV-25 01.16.01.541000000 PM     select * from emp where deptno = :deptId
sfBVyDyNXhkwsodUQDHMnAaa4nrlAeVt4_2SE0F5yX0iMwfJNgUhScUlZ2Og8u0I    DEMO_USER     2               15-NOV-25 03.57.33.997000000 PM     select * from emp where hiredate >= to_date(:b1,'dd-mon-yyyy')
gTqfJcv0JfckskdR7eI77QCUrMcMe5N4k1iXeeWstlo6c7uKxXQbyQQPotFTi10E    DEMO_USER     12              21-NOV-25 02.58.18.205000000 PM     select * from emp where deptno = :b1 and job = :b2
 
6 rows selected.
 
is_group_url = TRUE identifies group hyperlinks
 
To list the member hyperlinks of an existing table hyperlink group, we can do the below pl/sql call.

 
demo-user@ATP19C> declare
  2     l_status clob;
  3  begin
  4     dbms_data_access.list_members(
  5         id => 'JxfkVbJGWKYbD83nyC1wgcGTEuO2-6lzJDgN68V5Z7_Xf4OUTERg7CeUmXnU0RQh'
  6         , result => l_status );
  7     dbms_output.put_line( l_status );
  8  end;
  9* /
{
  "members" :
  [
    {
      "id" : "T_mxypj7jytHDoW5Li--q0Agxk_TKL3s2SZ46bJ0R6rMrDFa-X8lTLV5KjHsnEUk",
      "consistent" : false,
      "sql_statement" : " select empno,ename,hiredate,job,deptno from emp ",
      "name" : "Employees table",
      "description" : "Employees details"
    },
    {
      "id" : "9I6oXda2SKvyDfTu8cCsr8c9T_BOUqIHT0kz4qgvWWAHG3dWYfoWmrDTdriNHp0J",
      "consistent" : false,
      "schema_name" : "DEMO_USER",
      "schema_object_name" : "DEPT",
      "name" : "Department table",
      "description" : "Department details"
    }
  ]
}
 
You can add an existing standalone hyperlink to a group using add_member:
 
demo-user@ATP19C> declare
  2     l_status clob ;
  3  begin
  4     dbms_data_access.add_member(
  5         id => 'JxfkVbJGWKYbD83nyC1wgcGTEuO2-6lzJDgN68V5Z7_Xf4OUTERg7CeUmXnU0RQh'
  6         , member_id =>'v09slcWFCCHUgaH3XEEqqwMQClpSHabYebpYPaFp6Z3vsdnT6An8CZeCmfJv0-Oy'
  7         , result => l_status );
  8     dbms_output.put_line( l_status );
  9  end;
 10* /
{
  "status" : "SUCCESS"
}
 
 
Verifying the update group members
 
demo-user@ATP19C> declare
  2     l_status clob;
  3  begin
  4     dbms_data_access.list_members(
  5         id => 'JxfkVbJGWKYbD83nyC1wgcGTEuO2-6lzJDgN68V5Z7_Xf4OUTERg7CeUmXnU0RQh'
  6         , result => l_status );
  7     dbms_output.put_line( l_status );
  8  end;
  9* /
{
  "members" :
  [
    {
      "id" : "T_mxypj7jytHDoW5Li--q0Agxk_TKL3s2SZ46bJ0R6rMrDFa-X8lTLV5KjHsnEUk",
      "consistent" : false,
      "sql_statement" : " select empno,ename,hiredate,job,deptno from emp ",
      "name" : "Employees table",
      "description" : "Employees details"
    },
    {
      "id" : "v09slcWFCCHUgaH3XEEqqwMQClpSHabYebpYPaFp6Z3vsdnT6An8CZeCmfJv0-Oy",
      "consistent" : false,
      "sql_statement" : " select * from emp where deptno = :deptId "
    },
    {
      "id" : "9I6oXda2SKvyDfTu8cCsr8c9T_BOUqIHT0kz4qgvWWAHG3dWYfoWmrDTdriNHp0J",
      "consistent" : false,
      "schema_name" : "DEMO_USER",
      "schema_object_name" : "DEPT",
      "name" : "Department table",
      "description" : "Department details"
    }
  ]
}
 
 
Accessing the New Member with Bind Variables, include them as query parameters:
 
$ curl --location 'https://dataaccess.adb.us-ashburn-1.oraclecloudapps.com/adb/p/GW147LdUM4iIPKAsgNe2NIoByKCCGThJN4RKlrxHkcv7x_erMFkD8GQsgjprD64on7lQML_f2v8/data?member_id=v09slcWFCCHUgaH3XEEqqwMQClpSHabYebpYPaFp6Z3vsdnT6An8CZeCmfJv0-Oy&deptId=10'
 
{
  "items": [
    {
      "EMPNO": 7839,
      "ENAME": "KING",
      "JOB": "PRESIDENT",
      "HIREDATE": "1981-11-17T00:00:00",
      "SAL": 5000,
      "DEPTNO": 10
    },
    {
      "EMPNO": 7782,
      "ENAME": "CLARK",
      "JOB": "MANAGER",
      "MGR": 7839,
      "HIREDATE": "1981-06-09T00:00:00",
      "SAL": 2450,
      "DEPTNO": 10
    },
    {
      "EMPNO": 7934,
      "ENAME": "MILLER",
      "JOB": "CLERK",
      "MGR": 7782,
      "HIREDATE": "1982-01-23T00:00:00",
      "SAL": 1300,
      "DEPTNO": 10
    }
  ],
  "hasMore": false,
  "limit": 1000,
  "offset": 0,
  "count": 3,
  "links": [
    {
      "rel": "self",
      "href": "https://dataaccess.adb.us-ashburn-1.oraclecloudapps.com/adb/p/GW147LdUM4iIPKAsgNe2NIoByKCCGThJN4RKlrxHkcv7x_erMFkD8GQsgjprD64on7lQML_f2v8/data?member_id=v09slcWFCCHUgaH3XEEqqwMQClpSHabYebpYPaFp6Z3vsdnT6An8CZeCmfJv0-Oy&deptId=10"
    }
  ]
}
 
 
 
Table Hyperlink Groups provide: 
  •  A single, central access point for multiple data sources
  • Simplified integration with external applications
  • Easier control over permissions and lifecycle
  • Support for both object-based and SQL-query-based hyperlinks
  • Flexibility through bind variables 
This feature is particularly valuable when building lightweight APIs, exposing curated datasets, or integrating with downstream data pipelines.

No comments:

Post a Comment