はじめに
こちらの記事にあるようにAutonomous DatabaseのSelect AIは、様々なデータセットに対する横串検索(Fedarated Query)が可能です。
Sidecarですべての人のためのデータ・アンロック: AIドリブンのインサイトによるビジネス・ユーザーのパワーアップ
Serverles(ADB-S)だけでなく、Dedicated(ADB-D)でも実現できるので、ADB-DのADBに日本語で問い合わせをしてSnowflakeとADBのデータから結果を返してもらうことを試してみました。
前提
以下の構成での検証となります。
-
大阪リージョンで構築
-
パブリック・サブネットの踏み台のComuputeからプライベート・サブネットのDatabase Gateway用のComputeとADB-Dにアクセスします。
-
ADB-D、Computeの構築手順は含みません。Database Gateway用のComputeはドキュメントのハードウェア要件、ソフトウェア要件に適したComputeが必要です。MOSのKB105044でOracle Linux8も記載されていたので、今回はOracle Linux8をADB-Dと同じプライベート・サブネットに配置しています。(SnowflakeのODBCサポートがRedhatしか記述がなかったことに後で気づきましたが、検証なので。。)
-
ADB、Database Gatewayのバージョンは26aiを利用
-
Snowflakeはフリートライアルアカウントを利用。手順は含みません。
-
サンプルの表はEMPとDEPTを作成(動作確認なので簡単なものにしてます)
-
ocicliの設定手順は含みません。
1.SELECT AIの設定と確認
まずADB-DからSELECT AIで自然言語で問い合わせができるように設定します。踏み台からADB-DにADMINユーザーで接続します。
$ sqlplus admin/<パスワード>@ADB-Dへの接続文字列
-- select aiを実行するユーザーを作成。DBLINKを後で利用するのでDBLINKに関連する権限も付与
create user select_ai_user1 identified by "<パスワード>";
grant connect,resource,dwrole to select_ai_user1;
grant unlimited tablespace to select_ai_user1;
GRANT EXECUTE ON DBMS_CLOUD_AI TO select_ai_user1;
GRANT EXECUTE ON DBMS_CLOUD_ADMIN TO select_ai_user1;
GRANT CREATE ANY DIRECTORY TO select_ai_user1;
GRANT create database link to select_ai_user1;
exit;
作成したユーザーSELECT_AI_USER1でログインしなおし、サンプル表としてEMP表を作成します。
$ sqlplus select_ai_user1/<パスワード>@ADB-Dへの接続文字列
create table emp(
empno number(4,0),
ename varchar2(10),
job varchar2(9),
mgr number(4,0),
hiredate date,
sal number(7,2),
comm number(7,2),
deptno number(2,0));
insert into emp values(7839,'KING','PRESIDENT',null,to_date('17-11-1981','dd-mm-yyyy'),5000,null,10);
insert into emp values(7698,'BLAKE','MANAGER',7839,to_date('1-5-1981','dd-mm-yyyy'),2850,null,30);
insert into emp values(7782,'CLARK','MANAGER',7839,to_date('9-6-1981','dd-mm-yyyy'),2450,null,10);
insert into emp values(7566,'JONES','MANAGER',7839,to_date('2-4-1981','dd-mm-yyyy'),2975, null,20);
insert into emp values(7788,'SCOTT','ANALYST',7566,to_date('13-JUL-87','dd-mm-rr')-85,3000,null,20);
insert into emp values(7902,'FORD','ANALYST',7566,to_date('3-12-1981','dd-mm-yyyy'),3000,null,20);
insert into emp values(7369,'SMITH','CLERK',7902,to_date('17-12-1980','dd-mm-yyyy'),800,null,20);
insert into emp values(7499,'ALLEN','SALESMAN',7698,to_date('20-2-1981','dd-mm-yyyy'),1600,300,30);
insert into emp values(7521,'WARD','SALESMAN',7698,to_date('22-2-1981','dd-mm-yyyy'),1250,500,30);
insert into emp values(7654,'MARTIN','SALESMAN',7698,to_date('28-9-1981','dd-mm-yyyy'),1250,1400,30);
insert into emp values(7844,'TURNER','SALESMAN',7698,to_date('8-9-1981','dd-mm-yyyy'),1500,0,30);
insert into emp values(7876,'ADAMS','CLERK',7788,to_date('13-JUL-87','dd-mm-rr')- 51,1100,null,20);
insert into emp values(7900,'JAMES','CLERK',7698,to_date('3-12-1981','dd-mm-yyyy'),950,null,30);
insert into emp values(7934,'MILLER','CLERK',7782,to_date('23-1-1982','dd-mm-yyyy'),1300,null,10);
commit;
続けてクレデンシャル、プロファイルを作成します。クレデンシャルとプロファイルの作成の詳細についてはチュートリアルの111: SELECT AIを試してみようをご確認いただくとよいと思います。
-- クレデンシャルの作成
BEGIN
DBMS_CLOUD.CREATE_CREDENTIAL(
credential_name => 'OCI_KEY_CRED',
user_ocid => 'ocid1.user.oc1..axxxxxxxxxxxxxxxxq',
tenancy_ocid => 'ocid1.tenancy.oc1..aaxxxxxxxxxxxxa',
private_key => '-----BEGIN PRIVATE KEY-----
MIIEvAIBADANBgkqhkiGQEFA<中略>1D3iheu1ct50SB0aIQz9Ow==
-----END PRIVATE KEY-----',
fingerprint => 'xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx'
);
END;
/
-- プロファイルの作成
BEGIN
DBMS_CLOUD_AI.CREATE_PROFILE(
'GENAI_COHERE_COMMAND_R',
'{
"provider": "oci",
"credential_name": "OCI_KEY_CRED",
"model":"cohere.command-r-08-2024",
"region": "ap-osaka-1",
"oci_apiformat":"COHERE",
"object_list": [
{"owner": "SELECT_AI_USER1", "name": "EMP"}
]
}'
);
END;
/
-- 作成したプロファイルの確認
select * from user_cloud_ai_profiles;
select * from user_cloud_ai_profile_attributes where profile_name='GENAI_COHERE_COMMAND_R';
exit
自然言語での問い合わせを実行してみます。
キャッシュ機能の影響を避けるため、DBMS_CLOUD_AIパッケージで実行を行いました。EMP表に対し従業員は何名でいますか、と日本語で質問し、結果を得ています。一方で現在ない部門に関する質問については、生成したSQLに含まれる表の情報がなくエラーとなりました。
-- 日本語問い合わせができるよう設定
$ export LANG=ja_JP.utf8
$ export NLS_LANG=JAPANESE_JAPAN.UTF8
SQL*Plusでログイン
$ sqlplus select_ai_user1/<パスワード>@ADB-Dへの接続文字列
-- SELECT AIの実行(runsql)
-- 日本語の質問に対して正しく結果が返される
SELECT
DBMS_CLOUD_AI.GENERATE(
prompt => '従業員は何名いますか',
profile_name => 'GENAI_COHERE_COMMAND_R',
action => 'runsql'
) "回答"
FROM dual;
回答
--------------------------------------------------------------------------------
[
{
"Employee Count" : 14
}
-- DEPT表の情報はないのでエラーになる
SELECT
DBMS_CLOUD_AI.GENERATE(
prompt => '部門番号10の部署名と場所を表示してください',
profile_name => 'GENAI_COHERE_COMMAND_R',
action => 'runsql'
) "回答"
FROM dual;
回答
--------------------------------------------------------------------------------
Sorry, unfortunately a valid SELECT statement could not be generated for your
natural language prompt. Here is some more informati
on to help you further:
SELECT e."ENAME" AS "部署名", d."LOC" AS "場所"
FROM "SELECT_AI_USER1"."EMP" e
JOIN "SELECT_AI_USER1"."DEPT" d ON e."DEPTNO" = d."DEPTN
O"
WHERE d."DEPTNO" = 10
Exception encountered: ORA-00942: 表またはビュー "SELECT_AI
_USER1"."DEPT"は存在しません
2.Snowflake側の準備
フリートライアルでEnterprise Editionを選択しました。こちらでSnowflakeへのアクセスには今後キーペア認証または外部OAuthが必要になるとあったのですが、現在Oracleのデータベースリンクはパスワード認証です。そのため、Snowflakeにリーダーアカウントを作成してそちらにユーザーを作りアクセスさせることにしてみました。
サンプル表の所有ユーザーと表を作成
ACCOUNTADMINロールを持つユーザでログインし、まず、ワークスペースでSQLファイルを開き、ユーザーと表を作成します。
-- ロールを作成し、権限を付与
CREATE ROLE source_user_role;
GRANT USAGE ON WAREHOUSE compute_wh TO ROLE source_user_role;
GRANT ROLE SYSADMIN TO ROLE source_user_role;
-- ユーザーを作成
CREATE USER source_user1
PASSWORD = '<パスワード>'
DEFAULT_WAREHOUSE = COMPUTE_WH
DEFAULT_NAMESPACE = SOURCE_DB
DEFAULT_ROLE = source_user_role
DEFAULT_SECONDARY_ROLES = ( 'ALL' )
COMMENT = 'Source DB user for ODBC connection from Oracle to Snowflake';
-- ロールを付与
GRANT ROLE source_user_role TO USER source_user1;
サインアウトし、作成したユーザーsource_user1でサインインします。
ワークスペースでSQLファイルを追加し以下のSQLを実行し、結果が返されることを確認します。
-- データベースの作成
CREATE OR ALTER DATABASE source_db;
-- スキーマの作成
CREATE OR ALTER SCHEMA source_schema;
-- サンプル表DEPTの作成とデータ投入
CREATE OR REPLACE TABLE source_schema.dept (
deptno number(2,0),
dname varchar2(14),
loc varchar2(13));
insert into source_schema.dept values(10, 'ACCOUNTING', 'NEW YORK');
insert into source_schema.dept values(20, 'RESEARCH', 'DALLAS');
insert into source_schema.dept values(30, 'SALES', 'CHICAGO');
insert into source_schema.dept values(40, 'OPERATIONS', 'BOSTON');
--確認
select * from source_schema.dept;
リーダーアカウントと参照ユーザーの作成
ACCOUNTADMINロールを持つユーザでログインし、リーダーアカウントの作成を行います。
-- リーダーアカウントを作成
CREATE MANAGED ACCOUNT READER_ACCOUNT
admin_name = READER_ADMIN,
admin_password = '<パスワード>',
type = READER;
こちらのような結果が返されます。"accountName"、"accountLocator"、"url"は後で必要となります。
{"accountName":"READER_ACCOUNT","accountLocator":"xxxxxx","url":"https://*******-reader_account.snowflakecomputing.com","accountLocatorUrl":"https://xxxxxx.japan-east.azure.snowflakecomputing.com"}
続けて、共有を作成します。作成した共有に必要な権限を付与し、リーダーアカウントを追加します。リーダーアカウントの追加には先に確認した"accountLocator"の値を使います。
-- shareの作成
CREATE SHARE share_ora_test
-- shareに参照権限を付与
GRANT USAGE ON DATABASE source_db TO SHARE share_ora_test;
GRANT USAGE ON SCHEMA source_db.source_schema TO share share_ora_test;
GRANT SELECT ON ALL TABLES IN SCHEMA source_db.source_schema TO SHARE share_ora_test;
--shareにアカウントを追加
ALTER SHARE share_ora_test ADD ACCOUNTS = '<accountLocatorの値>';
リーダーアカウント作成時に確認した"URL"にアクセスし、管理ユーザ(この記事ではreader_admin)でログインします。
SQLワークシートで共有を確認し、owner_acccountの値を確認します。
-- 共有の確認
SHOW SHARES;
共有からデータベースを作成します。共有は"確認したowner_accountの値.共有名"の形で指定します。続けてリーダーアカウント用にウェアハウスを作成し、それを利用して表を確認してみます。
-- 参照用のDBを作成
CREATE DATABASE shared_db FROM SHARE <owner_accountの値>.share_ora_test;
-- ウェアハウスの作成
CREATE OR REPLACE WAREHOUSE reader_wh WITH
warehouse_size='XSMALL'
MAX_CLUSTER_COUNT=1
AUTO_SUSPEND=180 // 3分間実行がなければ自動停止
AUTO_RESUME=TRUE // クエリ実行時に自動でWH起動
INITIALLY_SUSPENDED=TRUE
--確認
SELECT * FROM shared_db.source_schema.dept;
確認ができたので、参照用のロールとユーザーを作成します。
-- ロールを作成し、権限を付与
CREATE ROLE ORA_READER_ROLE;
GRANT IMPORTED PRIVILEGES ON DATABASE shared_db TO ROLE ora_reader_role;
GRANT USAGE ON WAREHOUSE reader_wh TO ROLE ora_reader_role;
-- ユーザーを作成
CREATE USER ora_reader
PASSWORD = '<パスワード>'
DEFAULT_WAREHOUSE = READER_WH
DEFAULT_NAMESPACE = SHARED_DB
DEFAULT_ROLE = ORA_READER_ROLE
DEFAULT_SECONDARY_ROLES = ( 'ALL' )
COMMENT = 'User for ODBC connection from Oracle to Snowflake';
-- ロールを付与
GRANT ROLE ora_reader_role TO USER ora_reader;
3.Oracle Database Gatewayの準備
Oracle Database Gatewayのダウンロード
Oracle Software Delivery CloudからOracle AI Database Database Gateways 23.26.1.0.0をwgetオプションでComputeにダウンロードしました。
OTNのダウンロードサイトからもOracle Database 26ai for Linux x86-64のIndividual Component Downloadsをクリックし、Oracle AI Database 26ai Gateways (23.26.1) for Linux x86-64でLINUX.X64_2326100_gateways.zipをダウンロードできます。
Oracle Database Gatewayのインストール
踏み台にssh接続するための秘密鍵を配置して、インストール先のComputeにopcユーザでログインします。
--踏み台のopcユーザーで実行
$ ssh -i <フルパスの秘密鍵ファイル> <インストール先のComputeのIPアドレス>
[opc@インストール先のCompute名 ~]$
oracleユーザーを作成し、26aiに必要なパッケージをインストールしてから、ソフトウェアをダウンロード、解凍します。
-- rootにスイッチし、プリインストールパッケージをインストール.oracleユーザーも作成される
$ sudo su -
# dnf -y install oracle-ai-database-preinstall-26ai
-- インストール先のディレクトリを作成
-- 任意のディレクトリにもインストールできるのですが、OFAに準拠した構成にします。
# mkdir -p /u01/app/oracle/product/26ai/tghome_1
# mkdir -p /u01/app/oraInventory
# chown -R oracle:oinstall /u01/app/
# chmod -R 775 /u01/app
-- oracleユーザーにスイッチ
# sudo su - oracle
-- ダウンロードしたファイルを確認し、解凍
$ ls -ltr *.zip
-rw-r--r--. 1 oracle oinstall 890837112 Jan 23 06:40 V1054595-01.zip
$ unzip V1054595-01.zip
Oracle Database Gatewayのインストール
GUIでインストールすることもできますが、今回はレスポンスファイルを使ってインストールします。解凍したディレクトリの下にあるレスポンスファイルのサンプルをコピーし、編集します。
$ ls gateways/response
gateways.rsp netca.rsp
$ cp gateways/response/gateways.rsp /home/oracle
$ chmod 600 /home/oracle/gateways.rsp
--編集
$ vi gateways.rsp
--以下を編集しました。
UNIX_GROUP_NAME=oinstall
INVENTORY_LOCATION=/u01/app/oraInventory
ORACLE_HOME=/u01/app/oracle/product/26ai/tghome_1
ORACLE_BASE=/u01/app/oracle
oracle.install.tg.customComponents=oracle.rdbms.hsodbc:23.0.0.0.0
---
インストールを実行します。
-- サイレントインストールを実行
$ gateways/runInstaller -silent -noconfig -responseFile /home/oracle/gateways.rsp
Starting Oracle Universal Installer...
Checking Temp space: must be greater than 415 MB. Actual 22079 MB Passed
Checking swap space: must be greater than 150 MB. Actual 4095 MB Passed
Preparing to launch Oracle Universal Installer from /tmp/OraInstall2026-03-10_06-37-13AM. Please wait ...[oracle@adbgateway1 ~]$ The response file for this session can be found at:
/u01/app/oracle/product/26ai/tghome_1/install/response/gateways_2026-03-10_06-37-13AM.rsp
You can find the log of this install session at:
/tmp/OraInstall2026-03-10_06-37-13AM/installActions2026-03-10_06-37-13AM.log
The installation of Oracle Database Gateways was successful.
Please check '/u01/app/oraInventory/logs/silentInstall2026-03-10_06-37-13AM.log' for more details.
As a root user, run the following script(s):
1. /u01/app/oraInventory/orainstRoot.sh
2. /u01/app/oracle/product/26ai/tghome_1/root.sh
Successfully Setup Software.
The log of this install session can be found at:
/u01/app/oraInventory/logs/installActions2026-03-10_06-37-13AM.log
-- rootで指定されたスクリプトを実行
$ exit
# /u01/app/oraInventory/orainstRoot.sh
Changing permissions of /u01/app/oraInventory.
Adding read,write permissions for group.
Removing read,write,execute permissions for world.
Changing groupname of /u01/app/oraInventory to oinstall.
The execution of the script is complete.
# /u01/app/oracle/product/26ai/tghome_1/root.sh
Check /u01/app/oracle/product/26ai/tghome_1/install/root_adbgateway1_2026-03-10_06-53-21-907737071.log for the output of root script
SnowflakeのODBCをインストール
Snowflakeのドキュメントを参考にODBCを準備します。Snowflake ODBCのバージョンは3.6.0 and higherとあったので、3.6.0にしました。
-- rootにスイッチ
sudo su -
-- unixODBCのインストール
# dnf install unixODBC.x86_64
:
Installed:
unixODBC-2.3.7-2.el8_10.x86_64
-- 設定確認
# odbcinst -j
unixODBC 2.3.7
DRIVERS............: /etc/odbcinst.ini
SYSTEM DATA SOURCES: /etc/odbc.ini
FILE DATA SOURCES..: /etc/ODBCDataSources
USER DATA SOURCES..: /root/.odbc.ini
SQLULEN Size.......: 8
SQLLEN Size........: 8
SQLSETPOSIROW Size.: 8
# vi /etc/yum.repos.d/snowflake-odbc.repo
--以下を記述。
[snowflake-odbc]
name=snowflake-odbc
baseurl=https://sfc-repo.snowflakecomputing.com/odbc/linux/3.6.0/
gpgkey=https://sfc-repo.snowflakecomputing.com/odbc/Snowkey-2A3149C82551A34A-gpg
---
# dnf install snowflake-odbc
:
Downloading Packages:
snowflake-odbc-3.6.0.x86_64.rpm
:
Importing GPG key 0x2551A34A:
Userid : "Snowflake Computing (Snowflake Computing Gpg key) <snowflake_gpg@snowflake.net>"
Fingerprint: 8564 510C 6D19 3BB0 4E06 0306 2A31 49C8 2551 A34A
From : https://sfc-repo.snowflakecomputing.com/odbc/Snowkey-2A3149C82551A34A-gpg
Is this ok [y/N]: y
Key imported successfully
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
Preparing : 1/1
Installing : snowflake-odbc-3.6.0-1.x86_64 1/1
Running scriptlet: snowflake-odbc-3.6.0-1.x86_64 1/1
[WARN] SF_ACCOUNT is not set, please manually update the odbc.ini file after installation
Adding driver info to odbcinst.ini...
odbcinst: Driver installed. Usage count increased to 1.
Target directory is /etc
Adding connect info to odbc.ini...
odbcinst: Sections and Entries from stdin have been added to ODBC.INI
Adding Simba Snowflake ini...
Creating a symlink /usr/lib64/libodbccr.so.1...
Verifying : snowflake-odbc-3.6.0-1.x86_64 1/1
Installed:
snowflake-odbc-3.6.0-1.x86_64
Complete!
設定ファイルの編集を行います。
- vi /usr/lib64/snowflake/odbc/lib/simba.snowflake.ini
★を追記、または編集します。
[Driver]
DriverManagerEncoding=UTF-16
DriverLocale=en-US
ErrorMessagesPath=/usr/lib64/snowflake/odbc/ErrorMessages
LogNamespace=SHARE_ORA_TEST
LogPath=/tmp
ODBCInstLib=/usr/lib64/libodbcinst.so ★ フルパスに変更
CURLVerboseMode=false
#LogLevel=6
CABundleFile=/usr/lib64/snowflake/odbc/lib/cacert.pem
ANSIENCODING=UTF-8 ★
- vi /etc/odbcinst.ini
[ODBC_Drivers]を追加します。
# added
[ODBC Drivers]
SnowflakeDSIIDriver=Installed
- vi /etc/odbc.ini
[ODBC Data Sources]と[Snowflakeodbc1]を追加します。SERVERとACCOUNTにはSnowflakeのリーダーアカウントを作成したときに確認した値を入力します。
[ODBC Data Sources]
snowflakeodbc1 = SnowflakeDSIIDriver
[snowflakeodbc1]
Driver=/usr/lib64/snowflake/odbc/lib/libSnowflake.so
SERVER=<リーダーアカウントの"url">
ACCOUNT=<リーダーアカウントの"accountName">
Loglevel=0
LogPath=/var/tmp
インストール済みODBCの確認とisqlを利用して接続を確認します。
-- インストール済みのODBCの確認
$ odbcinst -q -d
-- isqlでログインをしてSQLを実行する
$ isql -v snowflakeodbc1 ora_reader <パスワード>
SQL> SELECT * FROM source_schema.dept;
SQL> quit
こちらのように結果が表示されました。
Gatewayの設定
初期化パラメータファイルの構成を行います。初期化パラメータの説明はドキュメントに記載があります。
$ORACLE_HOME/hs/adminにあるサンプルファイルをinit<任意のインスタンス名>.oraとしてコピーし編集します。
-- 環境変数を設定
# sudo su - oracle
$ export ORACLE_HOME=/u01/app/oracle/product/26ai/tghome_1
$ export PATH=$ORACLE_HOME/bin:$PATH
$ export LD_LIBRARY_PATH=$ORACLE_HOME/lib:$LD_LIBRARY_PATH
-- 初期化パラメータファイルのサンプルをコピー
$ cp $ORACLE_HOME/hs/admin/initdg4odbc.ora $ORACLE_HOME/hs/admin/initsnowflakedb1.ora
vi $ORACLE_HOME/hs/admin/initsnowflakedb1.ora
以下を編集します。HS_FDS_TRACE_LEVELはONにしていますが、詳細に出力させたいときはDEBUGを指定します。トレースは$ORACLE_HOME/hs/logに出力されます。
# HS init parameters
#
HS_FDS_CONNECT_INFO = snowflakeodbc1
HS_FDS_TRACE_LEVEL = ON
HS_FDS_SHAREABLE_NAME =/usr/lib64/snowflake/odbc/lib/libSnowflake.so
HS_LANGUAGE=AMERICAN_AMERICA.WE8ISO8859P1 ★MOS KB741074により追加
#
# ODBC specific environment variables
#
set ODBCINI= /etc/odbc.ini
:
# set <envvar>=<value> ★コメントにする
4.Autonomous DatabaseからDatabase Linkを作成するための準備
ドキュメントに記載があるとおり、パブリックにアクセス可能なOracle以外のデータベースへのデータベースリンクには前提条件があります。Database GatewayはSSL認証を使用するように構成しなければなりません。
Database Gatewayで自己署名付きウォレットの作成
Database GatewayのComputeで実施します。
# sudo su - oracle
$ mkdir -p /home/oracle/wallets/server/wallet
$ mkdir -p /home/oracle/wallets/client/wallet
-- サーバーウォレット作成
$ orapki wallet create -wallet /home/oracle/wallets/server/ -pwd <パスワード> -auto_login
$ orapki wallet add -wallet /home/oracle/wallets/server/ -pwd <パスワード> -dn "CN=dg4odbc" -keysize 1024 -self_signed -validity 3650 -sign_alg sha256
-- クライアントウォレット作成
$ orapki wallet create -wallet /home/oracle/wallets/client/ -pwd <パスワード> -auto_login
$ orapki wallet add -wallet /home/oracle/wallets/client/ -pwd <パスワード> -dn "CN=client" -keysize 1024 -self_signed -validity 3650 -sign_alg sha256
-- export
$ orapki wallet export -wallet /home/oracle/wallets/server/ -pwd <パスワード> -dn "CN=dg4odbc" -cert /home/oracle/wallets/server.crt
$ orapki wallet export -wallet /home/oracle/wallets/client/ -pwd <パスワード> -dn "CN=client" -cert /home/oracle/wallets/client.crt
-- import
$ orapki wallet add -wallet /home/oracle/wallets/server/ -pwd <パスワード> -trusted_cert -cert /home/oracle/wallets/client.crt
$ orapki wallet add -wallet /home/oracle/wallets/client/ -pwd <パスワード> -trusted_cert -cert /home/oracle/wallets/server.crt
-- それぞれの確認
$ orapki wallet display -wallet /home/oracle/wallets/server/
Oracle PKI Tool Release 23.0.0.0.0 - Production
Version 23.0.0.0.0
Copyright (c) 2004, 2026, Oracle and/or its affiliates. All rights reserved.
Requested Certificates:
User Certificates:
Subject: CN=dg4odbc
Trusted Certificates:
Subject: CN=client
Subject: CN=dg4odbc
$ orapki wallet display -wallet /home/oracle/wallets/client/
Oracle PKI Tool Release 23.0.0.0.0 - Production
Version 23.0.0.0.0
Copyright (c) 2004, 2026, Oracle and/or its affiliates. All rights reserved.
Requested Certificates:
User Certificates:
Subject: CN=client
Trusted Certificates:
Subject: CN=dg4odbc
Subject: CN=client
Database Gatewayリスナーの構成
SSL認証を利用するようにリスナーを構成します。
-- サーバ側のウォレットの権限変更
$ chmod 640 /home/oracle/wallets/server/cwallet.sso
---Listener.oraの作成
$ vi $ORACLE_HOME/network/admin/listener.ora
-- 以下の内容で作成
LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
(ADDRESS = (PROTOCOL = TCP)(HOST = ComputeのIPアドレス )(PORT = 1521))
(ADDRESS = (PROTOCOL = TCPS)(HOST = ComputeのIPアドレス )(PORT = 1522))
)
)
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC = (SID_NAME = snowflakedb1)(GLOBAL_DBNAME=dg4odbc_svc)
(ORACLE_HOME = /u01/app/oracle/product/26ai/tghome_1)
(PROGRAM = dg4odbc))
)
wallet_location =
(SOURCE=
(METHOD=File)
(METHOD_DATA=
(DIRECTORY=/home/oracle/wallets/server)))
--
--sqlnet.oraの作成
$ vi $ORACLE_HOME/network/admin/sqlnet.ora
--以下の内容で作成
wallet_location =
(SOURCE=
(METHOD=File)
(METHOD_DATA=
(DIRECTORY=/home/oracle/wallets/client)))
SSL_SERVER_DN_MATCH=TRUE
---
-- Listenerを起動
$ lsnrctl start
LSNRCTL for Linux: Version 23.26.1.0.0 - Production on 10-MAR-2026 07:27:57
Copyright (c) 1991, 2026, Oracle. All rights reserved.
Starting /u01/app/oracle/product/26ai/tghome_1/bin/tnslsnr: please wait...
TNSLSNR for Linux: Version 23.26.1.0.0 - Production
System parameter file is /u01/app/oracle/product/26ai/tghome_1/network/admin/listener.ora
Log messages written to /u01/app/oracle/diag/tnslsnr/adbgateway1/listener/alert/log.xml
Listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1521)))
Listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=ComputeのIPアドレス)(PORT=1521)))
Listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=tcps)(HOST=ComputeのIPアドレス)(PORT=1522)))
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC1521)))
STATUS of the LISTENER
------------------------
Alias LISTENER
Version TNSLSNR for Linux: Version 23.26.1.0.0 - Production
Start Date 10-MAR-2026 07:27:57
Uptime 0 days 0 hr. 0 min. 0 sec
Trace Level off
Security ON: Local OS Authentication
SNMP OFF
Listener Parameter File /u01/app/oracle/product/26ai/tghome_1/network/admin/listener.ora
Listener Log File /u01/app/oracle/diag/tnslsnr/adbgateway1/listener/alert/log.xml
Listening Endpoints Summary...
(DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1521)))
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=ComputeのIPアドレス)(PORT=1521)))
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcps)(HOST=ComputeのIPアドレス)(PORT=1522)))
Services Summary...
Service "dg4odbc_svc" has 1 instance(s).
Instance "snowflakedb1", status UNKNOWN, has 1 handler(s) for this service...
The command completed successfully
接続の確認用に接続文字列を用意して試してみます。
$ vi $ORACLE_HOME/network/admin/tnsnames.ora
以下の内容で作成
---
dg4odbc=
(DESCRIPTION=
(ADDRESS=(PROTOCOL=TCPS)(HOST=ComputeのIPアドレス)(PORT=1522))
(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=dg4odbc_svc)(HS=OK))
(SECURITY=(SSL_SERVER_DN_MATCH=TRUE)(SSL_SERVER_CERT_DN="CN=dg4odbc"))
)
---
-- 接続の確認
$ tnsping dg4odbc
TNS Ping Utility for Linux: Version 23.26.1.0.0 - Production on 10-MAR-2026 09:01:56
Copyright (c) 1997, 2026, Oracle. All rights reserved.
Used parameter files:
/u01/app/oracle/product/26ai/tghome_1/network/admin/sqlnet.ora
Used TNSNAMES adapter to resolve the alias
Attempting to contact (DESCRIPTION= (ADDRESS=(PROTOCOL=TCPS)(HOST=ComputeのIPアドレス)(PORT=1522)) (CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=dg4odbc_svc)(HS=OK)) (SECURITY=(SSL_SERVER_DN_MATCH=TRUE)(SSL_SERVER_CERT_DN=CN=dg4odbc)))
OK (0 msec))
外からアクセスするのでrootユーザーで1522ポートを解放します。
$ su - root
# firewall-cmd --add-port=1522/tcp --permanent
# firewall-cmd --reload
Autonomous Database側での設定
クライアントウォレットをAutonomous Databaseで読み込めるよう設定します。
ウオレットのObject Storageへのアップロード手順は手元のPCにダウンロードして、アップロードすることでも構いません。ここではocicliを利用して直接アップロードしています。
-- クライアントウォレットをObject Storageにアップロード
# cp /home/oracle/wallets/client/cwallet.sso /home/opc/
# chmod 777 /home/opc/cwallet.sso
# exit
-- ocicliを構成済みのopcユーザーで実行
$ oci os object put -ns テナンシー名 -bn バケット名 --name cwallet.sso --file /home/opc/cwallet.sso
次にAutonomous Databaseにアクセスし、クレデンシャルを作成していきます。
踏み台からADB-Dにselect_ai_user1で接続します。
$ sqlplus select_ai_user1/<パスワード>@ADB-Dへの接続文字列
--ディレクトリ作成
create directory dblink_wallet_dir as 'walletdir';
-- クレデンシャルが正しいかアップロード先のObject Storageの参照を実行
select * from
DBMS_CLOUD.LIST_OBJECTS(
credential_name => 'OCI_KEY_CRED',
location_uri => 'https://objectstorage.ap-osaka-1.oraclecloud.com/n/テナンシ名/b/バケット名/o');
-- ディレクトリにウォレットをコピー
BEGIN
DBMS_CLOUD.GET_OBJECT(
credential_name => 'OCI_KEY_CRED',
object_uri => 'https://objectstorage.ap-osaka-1.oraclecloud.com/n/テナンシ名/b/バケット名/o/cwallet.sso',
directory_name => 'dblink_wallet_dir');
END;
/
-- コピーしたウォレットの確認
SELECT object_name,created,last_modified FROM table(dbms_cloud.list_files('DBLINK_WALLET_DIR')) WHERE object_name LIKE '%.sso';
OBJECT_NAME
--------------------------------------------------------------------------------
CREATED
---------------------------------------------------------------------------
LAST_MODIFIED
---------------------------------------------------------------------------
cwallet.sso
10-MAR-26 07.57.35.600820 AM +00:00
10-MAR-26 07.57.35.642449 AM +00:00
5.Autonomous DatabaseでDatabase Linkを作成
Snowflakeに対してデータベース・リンクを作成し、データベース・リンク経由でのSnowflakeへの検索を確認します。
-- Snowflake用の接続のクレデンシャルを作成
BEGIN
DBMS_CLOUD.CREATE_CREDENTIAL(
credential_name => 'DB_LINK_CRED',
username => 'ORA_READER',
password => '<パスワード>'
);
END;
/
-- Database Gatewayを利用したデータベースリンクを作成
BEGIN
DBMS_CLOUD_ADMIN.CREATE_DATABASE_LINK(
db_link_name => 'SNOWFLAKEDB1LINK',
hostname => 'ComputeのIPアドレス',
port => '1522',
service_name => 'DG4ODBC_SVC',
ssl_server_cert_dn => 'CN=dg4odbc',
credential_name => 'DB_LINK_CRED',
directory_name => 'DBLINK_WALLET_DIR',
gateway_link => TRUE
);
END;
/
-- 接続の動作確認
SQL> SELECT * FROM SOURCE_SCHEMA.DEPT@snowflakedb1link;
DEPTNO DNAME LOC
---------- ---------- --------------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
6.SELECT AIで問い合わせる
データベースリンクでSnowflakeのDEPT表の参照が確認できました。続けて、プロファイルに指定ができるようにビューを作成し、そのビューを参照できるようプロファイルを更新します。
-- ビューの作成
CREATE VIEW dept AS SELECT * FROM source_schema.dept@snowflakedb1link;
-- プロファイルを更新
BEGIN
DBMS_CLOUD_AI.SET_ATTRIBUTE(
profile_name => 'GENAI_COHERE_COMMAND_R',
attribute_name => 'object_list',
attribute_value => '[{"owner": "SELECT_AI_USER1", "name": "EMP"},
{"owner": "SELECT_AI_USER1", "name": "DEPT"}]' );
END;
/
改めてSELECT AIで問い合わせてみます。
-- 日本語問い合わせができるよう設定
$ export LANG=ja_JP.utf8
$ export NLS_LANG=JAPANESE_JAPAN.UTF8
SQL*Plusでログイン
$ sqlplus select_ai_user1/<パスワード>@ADB-Dへの接続文字列
-- SELECT AIの実行(runsql)
-- 日本語の質問に対して正しく結果が返される
SELECT
DBMS_CLOUD_AI.GENERATE(
prompt => '従業員は何名いますか',
profile_name => 'GENAI_COHERE_COMMAND_R',
action => 'runsql'
) "回答"
FROM dual;
回答
--------------------------------------------------------------------------------
[
{
"Employee Count" : 14
}
]
-- SnowflakeにあるDEPT表の内容を検索する質問をしてみる。
SELECT
DBMS_CLOUD_AI.GENERATE(
prompt => '部門番号10の部署名と場所を表示してください',
profile_name => 'GENAI_COHERE_COMMAND_R',
action => 'runsql'
) "回答"
FROM dual;
回答
--------------------------------------------------------------------------------
[
{
"部門番号" : 10,
"部署名" : "ACCOUNTING",
"場所" : "NEW YORK"
}
]
-- SnowflakeにあるDEPTとADB-DのEMP表を結合して検索する質問をしてみる。
SELECT
DBMS_CLOUD_AI.GENERATE(
prompt => '部門番号が10の部門名と従業員名を表示して',
profile_name => 'GENAI_COHERE_COMMAND_R',
action => 'runsql'
) "回答"
FROM dual;
回答
--------------------------------------------------------------------------------
[
{
"部門番号" : 10,
"部門名" : "ACCOUNTING",
"従業員名" : "KING"
},
{
"部門番号" : 10,
"部門名" : "ACCOUNTING",
"従業員名" : "CLARK"
},
{
"部門番号" : 10,
"部門名" : "ACCOUNTING",
"従業員名" : "MILLER"
}
]
-- SQLを確認
SELECT
DBMS_CLOUD_AI.GENERATE(
prompt => '部門番号が10の部門名と従業員名を表示して',
profile_name => 'GENAI_COHERE_COMMAND_R',
action => 'showsql'
) "回答"
FROM dual;
回答
--------------------------------------------------------------------------------
SELECT
d."DEPTNO" AS "部門番号",
d."DNAME" AS "部門名",
e."ENAME" AS "従業員名"
FROM
"SELECT_AI_USER1"."DEPT" d
JOIN
"SELECT_AI_USER1"."EMP" e ON d."DEPTNO" = e."DEPTNO
"
WHERE
d."DEPTNO" = 10
期待通りの結果を得ることができました。
おわりに
ADB-DのADBに日本語で問い合わせをしてSnowflakeとADBのデータから結果を返してもらうことができました。
参考資料
- Database Gateway for APPC Installation and Configuration Guide for AIX 5L Based Systems (64-Bit), HP-UX Itanium, Solaris Operating System (SPARC 64-Bit), Linux x86, and Linux x86-64)
- Snowflakeを使ってみた!無料トライアルのやり方をわかりやすく解説
- https://www.snowdba.com/connect-to-snowflake-from-oracle/
- Create Database Links with Customer-Managed Heterogeneous Connectivity to Publicly Accessible Non-Oracle Databases
- How to Access Non-Oracle Databases from Autonomous Database using Oracle Database Gateway
- (KB741074)Error Ora-28500 and Sqlstate I or Displays a Square Bracket - [ - Issuing Selects From a Unicode Oracle RDBMS With Dg4odbc To Non-Oracle Databases Using the UnixODBC Driver Manager (Doc ID 756186.1)
- [ADW/ATP] Users other than admin can not create database link by ora-01031 (Doc ID 2561130.1)







