はじめに
10/2 の TechNight で紹介されていたテーブルハイパーリンクが面白そうだったので試してみました。
テーブルハイパーリンクは データ共有手法のひとつ で、Autonomous AI Database の表やビューに対してハイパーリンクを生成し、OCI のアカウントを持っていないユーザにもデータ共有が可能です。
ブラウザでテーブルハイパーリンクを指定するか、RESTクライアントを使用してデータにアクセスできます。
TechNight の資料はこちら↓ (テーブルハイパーリンクについては P13以降)
参考にしたドキュメントは下記
テーブルハイパーリンクの生成
ドキュメントを見ると、
表ハイパーリンクを生成するユーザーには、データへのアクセスを提供するために必要な最小限の権限が必要です。セキュリティを維持するために、Oracleでは、ADMINユーザーとしてDBMS_DATA_ACCESS.CREATE_URLを実行しないことをお薦めします。
とのことなので、TBHLユーザを作成しDBMS_DATA_ACCESSの実行権限を付与しました。
DBMS_DATA_ACCESS.CREATE_URLを使用して SHスキーマの CHANNELS表に対してハイパーリンクを生成します。
expiration_minutesにハイパーリンクの有効期間を指定することができます。(今回は5分)
SQL>
SQL> sho user
USER is "TBHL"
SQL>
SQL> DECLARE
status CLOB;
BEGIN
DBMS_DATA_ACCESS.CREATE_URL(
schema_name => 'SH',
schema_object_name => 'CHANNELS',
expiration_minutes => 5,
result => status);
dbms_output.put_line(status);
END;
/
2 3 4 5 6 7 8 9 10 11 {
"status" : "SUCCESS",
"id" :
"KpcV0TJw7ZwWp5Ga2bVrb7rLMoYr2czIkd94O1FNJnmGXsYPhbMm6CVRclj8X2Mj",
"preauth_url" :
"https://dataaccess.adb.ap-tokyo-1.oraclecloudapps.com/adb/p/3-NcC3Lw0PXCn57v0DT
NBhlTIKCkOalfc1GKr6smXm6MhIbNhJFRNf9n_fE5a-qvO2fQniGPD2Q/data",
"expiration_ts" : "2025-10-20T05:35:33.190Z"
}
PL/SQL procedure successfully completed.
SQL>
生成されたハイパーリンクに Chrome からアクセスすると、JSON形式で CHANNELS表のデータを参照することができました。
{
"items": [
{
"CHANNEL_ID": 3,
"CHANNEL_DESC": "Direct Sales",
"CHANNEL_CLASS": "Direct",
"CHANNEL_CLASS_ID": 12,
"CHANNEL_TOTAL": "Channel total",
"CHANNEL_TOTAL_ID": 1
},
{
"CHANNEL_ID": 9,
"CHANNEL_DESC": "Tele Sales",
"CHANNEL_CLASS": "Direct",
"CHANNEL_CLASS_ID": 12,
"CHANNEL_TOTAL": "Channel total",
"CHANNEL_TOTAL_ID": 1
},
{
"CHANNEL_ID": 5,
"CHANNEL_DESC": "Catalog",
"CHANNEL_CLASS": "Indirect",
"CHANNEL_CLASS_ID": 13,
"CHANNEL_TOTAL": "Channel total",
"CHANNEL_TOTAL_ID": 1
},
{
"CHANNEL_ID": 4,
"CHANNEL_DESC": "Internet",
"CHANNEL_CLASS": "Indirect",
"CHANNEL_CLASS_ID": 13,
"CHANNEL_TOTAL": "Channel total",
"CHANNEL_TOTAL_ID": 1
},
{
"CHANNEL_ID": 2,
"CHANNEL_DESC": "Partners",
"CHANNEL_CLASS": "Others",
"CHANNEL_CLASS_ID": 14,
"CHANNEL_TOTAL": "Channel total",
"CHANNEL_TOTAL_ID": 1
}
],
"hasMore": false,
"limit": 1000,
"offset": 0,
"count": 5,
"links": [
{
"rel": "self",
"href": "https://dataaccess.adb.ap-tokyo-1.oraclecloudapps.com/adb/p/3-NcC3Lw0PXCn57v0DTNBhlTIKCkOalfc1GKr6smXm6MhIbNhJFRNf9n_fE5a-qvO2fQniGPD2Q/data"
}
]
}
DBMS_DATA_ACCESS.LIST_ACTIVE_URLSを使用して現在有効なハイパーリンクを確認することができます。
先ほど生成したハイパーリンクのアクセス数や期限の切れる日時が表示されました。
SQL>
SQL> DECLARE
result CLOB;
BEGIN
result := DBMS_DATA_ACCESS.LIST_ACTIVE_URLS;
DBMS_OUTPUT.PUT_LINE(result);
END;
/ 2 3 4 5 6 7
[
{
"id" :
"KpcV0TJw7ZwWp5Ga2bVrb7rLMoYr2czIkd94O1FNJnmGXsYPhbMm6CVRclj8X2Mj",
"created_by" : "TBHL",
"service_name" : "LOW",
"consistent" : false,
"expiration_time" : "2025-10-20T05:35:33.190Z",
"access_count" : 1,
"created" : "2025-10-20T05:30:33.215Z",
"schema_name" : "SH",
"schema_object_name" : "CHANNELS"
}
]
PL/SQL procedure successfully completed.
SQL>
期限切れ後のハイパーリンクに再度アクセスすると、表示は下記のようになりました。
{"code":"ADB-09009","message":"Table Hyperlink not found or not authorized."}
テーブルハイパーリンクの生成と有効期間の延長
先ほどと同様 SHスキーマの CHANNELS表に対してハイパーリンクを生成しました。
ハイパーリンクを生成するテーブルが同じであっても、IDとハイパーリンクは都度変わるようです。
SQL> DECLARE
status CLOB;
BEGIN
DBMS_DATA_ACCESS.CREATE_URL(
schema_name => 'SH',
schema_object_name => 'CHANNELS',
expiration_minutes => 30,
result => status);
dbms_output.put_line(status);
END;
/
2 3 4 5 6 7 8 9 10 11 {
"status" : "SUCCESS",
"id" :
"2aZM3x2avYDedx0quJiak4HSyzjesWdTmHQ6M2ZmL6AA5qNBYjtKICQMh5_HWkM6", ★
"preauth_url" :
"https://dataaccess.adb.ap-tokyo-1.oraclecloudapps.com/adb/p/xhzU7d58VA5mHiJ1hqw
LP-t4LVLEeB8ovd3DPuvpItoJ_TpW0LDvi9MD8cdTMfAEO2fQniGPD2Q/data", ★
"expiration_ts" : "2025-10-20T06:11:56.512Z"
}
PL/SQL procedure successfully completed.
SQL>
Chrome からアクセスした結果はもちろん変わりません。
{
"items": [
{
"CHANNEL_ID": 3,
"CHANNEL_DESC": "Direct Sales",
"CHANNEL_CLASS": "Direct",
"CHANNEL_CLASS_ID": 12,
"CHANNEL_TOTAL": "Channel total",
"CHANNEL_TOTAL_ID": 1
},
{
"CHANNEL_ID": 9,
"CHANNEL_DESC": "Tele Sales",
"CHANNEL_CLASS": "Direct",
"CHANNEL_CLASS_ID": 12,
"CHANNEL_TOTAL": "Channel total",
"CHANNEL_TOTAL_ID": 1
},
{
"CHANNEL_ID": 5,
"CHANNEL_DESC": "Catalog",
"CHANNEL_CLASS": "Indirect",
"CHANNEL_CLASS_ID": 13,
"CHANNEL_TOTAL": "Channel total",
"CHANNEL_TOTAL_ID": 1
},
{
"CHANNEL_ID": 4,
"CHANNEL_DESC": "Internet",
"CHANNEL_CLASS": "Indirect",
"CHANNEL_CLASS_ID": 13,
"CHANNEL_TOTAL": "Channel total",
"CHANNEL_TOTAL_ID": 1
},
{
"CHANNEL_ID": 2,
"CHANNEL_DESC": "Partners",
"CHANNEL_CLASS": "Others",
"CHANNEL_CLASS_ID": 14,
"CHANNEL_TOTAL": "Channel total",
"CHANNEL_TOTAL_ID": 1
}
],
"hasMore": false,
"limit": 1000,
"offset": 0,
"count": 5,
"links": [
{
"rel": "self",
"href": "https://dataaccess.adb.ap-tokyo-1.oraclecloudapps.com/adb/p/xhzU7d58VA5mHiJ1hqwLP-t4LVLEeB8ovd3DPuvpItoJ_TpW0LDvi9MD8cdTMfAEO2fQniGPD2Q/data"
}
]
}
DBMS_DATA_ACCESS.EXTEND_URLを使用してハイパーリンクの有効期間を延長することができます。
2025-10-20T06:11:56.512Z から 2025-10-20T07:11:56.512Z に延長されたことが確認できました。
SQL>
SQL> DECLARE
status CLOB;
BEGIN
DBMS_DATA_ACCESS.EXTEND_URL(
id => '2aZM3x2avYDedx0quJiak4HSyzjesWdTmHQ6M2ZmL6AA5qNBYjtKICQMh5_HWkM6',
extend_expiration_minutes_by => 60,
result => status);
dbms_output.put_line(status);
END;
/ 2 3 4 5 6 7 8 9 10
{
"status" : "SUCCESS"
}
PL/SQL procedure successfully completed.
SQL>
SQL>
SQL> DECLARE
result CLOB;
BEGIN
result := DBMS_DATA_ACCESS.LIST_ACTIVE_URLS;
DBMS_OUTPUT.PUT_LINE(result);
END;
/ 2 3 4 5 6 7
[
{
"id" :
"2aZM3x2avYDedx0quJiak4HSyzjesWdTmHQ6M2ZmL6AA5qNBYjtKICQMh5_HWkM6",
"created_by" : "TBHL",
"service_name" : "LOW",
"consistent" : false,
"expiration_time" : "2025-10-20T07:11:56.512Z", ★
"access_count" : 1,
"created" : "2025-10-20T05:41:56.536Z",
"schema_name" : "SH",
"schema_object_name" : "CHANNELS"
}
]
PL/SQL procedure successfully completed.
SQL>
テーブルハイパーリンクの生成 (SQL指定)
ここまではハイパーリンクを生成するテーブルのスキーマ名 (schema_name) とテーブル名 (schema_object_name) を指定していましたが、SQL (sql_statement) を指定することも可能です。
SQL>
SQL> DECLARE
status CLOB;
BEGIN
DBMS_DATA_ACCESS.CREATE_URL(
sql_statement => 'SELECT * FROM sh.channels WHERE channel_id = :channelid', ★
default_bind_values => '{"channelid" : 3}',
expiration_minutes => 60,
result => status);
dbms_output.put_line(status);
END;
/ 2 3 4 5 6 7 8 9 10 11
{
"status" : "SUCCESS",
"id" :
"sYKy7FwNhTwgJEI6wdtKyIRTkdjZWo_wbKSOlaica_jUGUT4jzBIaiK9rdBf5lKD",
"preauth_url" :
"https://dataaccess.adb.ap-tokyo-1.oraclecloudapps.com/adb/p/JG-Vu4vJjYTHvaHl3dS
3aRoV-NT9DnNfthLW_vD7xkG6xA0U7kg_vrsZofSAu9BUNiBH6QccS08/data",
"expiration_ts" : "2025-10-20T06:57:21.702Z"
}
PL/SQL procedure successfully completed.
SQL>
ハイパーリンクにアクセスすると、指定した SQL の実行結果が表示されました。
{
"items": [
{
"CHANNEL_ID": 3,
"CHANNEL_DESC": "Direct Sales",
"CHANNEL_CLASS": "Direct",
"CHANNEL_CLASS_ID": 12,
"CHANNEL_TOTAL": "Channel total",
"CHANNEL_TOTAL_ID": 1
}
],
"hasMore": false,
"limit": 1000,
"offset": 0,
"count": 1,
"links": [
{
"rel": "self",
"href": "https://dataaccess.adb.ap-tokyo-1.oraclecloudapps.com/adb/p/JG-Vu4vJjYTHvaHl3dS3aRoV-NT9DnNfthLW_vD7xkG6xA0U7kg_vrsZofSAu9BUNiBH6QccS08/data"
}
]
}
テーブルハイパーリンクの管理
V$DATA_ACCESS_URL_STATSを参照して、ハイパーリンクのアクセス数など統計情報を確認可能です。
SQL指定で生成したハイパーリンクにアクセスを繰り返すと、SQLID: 83nj5sgp1pdht の EXECUTIONS が増えている状況を確認できました。
SQL> desc V$DATA_ACCESS_URL_STATS
Name Null? Type
----------------------------------------- -------- ----------------------------
SQL_ID VARCHAR2(13)
ELAPSED_TIME NUMBER
CPU_TIME NUMBER
USER_IO_WAIT_TIME NUMBER
EXECUTIONS NUMBER
FETCHES NUMBER
ROWS_PROCESSED NUMBER
MODULE VARCHAR2(64)
ACTION VARCHAR2(64)
USER_ID VARCHAR2(128)
CON_ID NUMBER
SQL> select * from V$DATA_ACCESS_URL_STATS order by sql_id;
SQL_ID ELAPSED_TIME CPU_TIME USER_IO_WAIT_TIME EXECUTIONS FETCHES
------------- ------------ ---------- ----------------- ---------- ----------
ROWS_PROCESSED MODULE
-------------- ----------------------------------------------------------------
ACTION
----------------------------------------------------------------
USER_ID
--------------------------------------------------------------------------------
CON_ID
----------
3txg7pw4r1hsb 11966 11322 0 1 1
1 DATA$ACCESS
684415461
0
4m7zpk10uq4ws 6784 7029 0 2 2
2 DATA$ACCESS
2553129697
0
83nj5sgp1pdht 3602 4055 0 1 1
1 DATA$ACCESS
315210285
0
SQL>
SQL> select * from V$DATA_ACCESS_URL_STATS order by sql_id;
SQL_ID ELAPSED_TIME CPU_TIME USER_IO_WAIT_TIME EXECUTIONS FETCHES
------------- ------------ ---------- ----------------- ---------- ----------
ROWS_PROCESSED MODULE
-------------- ----------------------------------------------------------------
ACTION
----------------------------------------------------------------
USER_ID
--------------------------------------------------------------------------------
CON_ID
----------
3txg7pw4r1hsb 11966 11322 0 1 1
1 DATA$ACCESS
684415461
0
4m7zpk10uq4ws 6784 7029 0 2 2
2 DATA$ACCESS
2553129697
0
83nj5sgp1pdht 4609 5062 0 7 7
7 DATA$ACCESS
315210285
0
SQL>
SQLID をキーに SQL文を参照すると、主問い合わせは共通しており、副問い合わせがハイパーリンク生成時に指定した内容となっていることを確認できました。
JSON_OBJECT(* RETURNING CLOB)で副問い合わせ結果の各行を「列名: 値」のペアで JSONオブジェクト化、JSON_ARRAYAGG(... RETURNING CLOB)で行ごとの JSONオブジェクトを配列にまとめ、CLOB で返す形になっています。
SQL> SELECT sql_id, sql_fulltext, TO_CHAR(last_active_time, 'YYYY/MM/DD HH24:MI:SS')
FROM v$sql
WHERE sql_id IN ('83nj5sgp1pdht','4m7zpk10uq4ws','3txg7pw4r1hsb') order by 1; 2 3
SQL_ID
-------------
SQL_FULLTEXT
--------------------------------------------------------------------------------
TO_CHAR(LAST_ACTIVE
-------------------
3txg7pw4r1hsb
SELECT JSON_ARRAYAGG(JSON_OBJECT(* RETURNING CLOB) RETURNING CLOB), COUNT(*) FRO
M (SELECT * FROM SH.COUNTRIES OFFSET 0 ROWS FETCH NEXT 1000 +1 ROWS ONLY)
2025/10/20 05:19:54
4m7zpk10uq4ws
SELECT JSON_ARRAYAGG(JSON_OBJECT(* RETURNING CLOB) RETURNING CLOB), COUNT(*) FRO
M (SELECT * FROM SH.CHANNELS OFFSET 0 ROWS FETCH NEXT 1000 +1 ROWS ONLY)
2025/10/20 05:43:12
83nj5sgp1pdht
SELECT JSON_ARRAYAGG(JSON_OBJECT(* RETURNING CLOB) RETURNING CLOB), COUNT(*) FRO
M (SELECT * FROM sh.channels WHERE channel_id = :channelid OFFSET 0 ROWS FETCH N
EXT 1000 +1 ROWS ONLY)
2025/10/20 06:29:36
SQL>
JSON_OBJECT についてはこちら↓
JSON_ARRAYAGG についてはこちら↓
パスワードや ACL の設定も可能なようですので、データ共有に課題のある方は使用を検討してみてはいかがでしょうか ![]()
