OCIのAutonomous Database (ADB) には異種DBに対してDBLink接続する機能があります。
またADBにはSELECT AIという、生成AIを使って自然言語でデータアクセスする機能 (いわゆるNL2SQL) があります。
組み合わせる生成AIはOpenAIやAnthropic、Google、Cohereなど、多様なプロバイダーを選択できます。
またADBをハブとして、これら機能によりOracle DBや異種DBに対する横櫛検索を自然言語で実装する「Sidecar」というコンセプトがあります。
例えば部署毎に異なるDB製品を使っていてデータが散在している状況でも、ETLによるデータ統合なしに、ADB Sidecarですぐにデータ利活用できます。
さらにSQLを書くのが困難な方でも、日常的に使う自然言語でデータアクセス出来てしまいます。
今回はこの「Sidecar」を実際に試すべく、ADBからSnowflakeに対してSELECT AIによる自然言語での問い合わせを試してみました。
なお今回は異種DBとのDBLink機能を使っていますが、Apache Icebergを使った方法も別途記事にしたいと思います。
検証環境
OCI TokyoリージョンのADBと、AWS TokyoリージョンのSnowflakeを使いました。
検証手順
DBユーザ作成
ADB上に検証用ユーザを作成し、必要な権限を付与します。
今回は snow
というDBユーザを作成します。
GRANT DB_DEVELOPER_ROLE TO snow identified by <your password>;
GRANT EXECUTE ON DBMS_CLOUD TO snow;
GRANT EXECUTE ON DBMS_CLOUD_AI TO SNOW;
GRANT EXECUTE ON DBMS_CLOUD_ADMIN TO snow;
GRANT CREATE DATABASE LINK TO snow;
ALTER USER snow QUOTA UNLIMITED ON USERS;
SnowflakeへのDBLink作成
Snowflakeに対してDBLink接続するためのPL/SQLを実行します。
なお異種DB接続をサポートする他社DBはSnowflake以外にもAmazon RedshiftやDb2、PostgreSQL、SharePointなど様々あります。
接続する異種DBによってプロシージャの引数が変わりますので、対象DBの構文は以下コマンドでご確認ください。
SELECT * FROM HETEROGENEOUS_CONNECTIVITY_INFO WHERE DATABASE_TYPE = 'db product name';
-- Snowflakeの場合
SELECT * FROM HETEROGENEOUS_CONNECTIVITY_INFO WHERE DATABASE_TYPE = 'snowflake';
SnowflakeへDBLink接続するPL/SQLは以下になります。
-- Snowflakeに対するクレデンシャル作成
BEGIN
DBMS_CLOUD.CREATE_CREDENTIAL(
credential_name => 'SNOWFLAKE_CRED',
username => 'your snowflake account name',
password => 'your snowflake account password');
END;
/
-- SnowflakeへのDBLink作成
BEGIN
DBMS_CLOUD_ADMIN.CREATE_DATABASE_LINK(
db_link_name => 'SNOWFLAKE_LINK',
hostname => 'your snowflake host name',
port => '443',
service_name => 'your snowflake db name',
ssl_server_cert_dn => null,
credential_name => 'SNOWFLAKE_CRED',
gateway_params => JSON_OBJECT( 'db_type' value 'snowflake'));
END;
/
なお hostname
に入力する値はSnowflakeコンソールの「アカウント詳細」から確認できます。
左下のアカウント名のアイコンを選択し、アカウント > アカウントの詳細を表示する を選択します。
表示される「アカウント/サーバーURL」が該当箇所です。
Snowflakeにデータをロード
Snowflake上にはチュートリアル用のデータなど色々ありますが、今回は手元にあった orders.csv
というサンプルの受発注履歴データを使いました。
まずはワークスペースにてロード先のテーブルを作ります。
※DB名やテーブル名はご自分の環境に合わせて修正してください。
-- orders.csvの一部のカラムだけロードするテーブル
create or replace TABLE CYBERSYN.PUBLIC.ORDERS2 (
ID NUMBER(38,0),
ORDER_KEY NUMBER(38,0),
ORDER_STATUS VARCHAR(100)
);
Snowflakeコンソールのテーブル画面へアクセスし、右上にある「作成」からCSVをアップロードして作成したテーブルにロードします。
ADBからSnowflakeにDBLink経由で問い合わせしてみる
DBLink作成とデータロードが出来ましたので、試しにADBからSnowflakeへ問い合わせてみます。
今回はADBに付属するDatabase ActionsのSQL機能を使って問い合わせてみました。
SELECT count(*) FROM ORDERS2@SNOWFLAKE_LINK;
SELECT id, order_status FROM ORDERS2@SNOWFLAKE_LINK FETCH FIRST 10 ROWS ONLY;
ちゃんと結果が返ってきました。
Viewの作成
SELECT AIを使ってDBLink経由でデータ取得するにあたり、DBLinkを使ってSELECTするViewを作成します。
(後述のSELECT AI対象オブジェクトを登録するコマンドにおいて、DBLink付きのテーブルが登録できなかったための対応となります。)
CREATE VIEW ORDERS2_V AS SELECT ID, ORDER_KEY, ORDER_STATUS FROM ORDERS2@SNOWFLAKE_LINK;
SELECT AIの設定
SELECT AIを使えるように設定します。
まずは生成AIモデルを使うためのクレデンシャルを作成します。
今回はOCI Generative AI Serviceが提供するCohereの command-r-plus-08-2024
を使います。
-- OCIアカウントのクレデンシャルを作成
BEGIN
DBMS_CLOUD.CREATE_CREDENTIAL(
credential_name => 'OCI_GENAI',
user_ocid => 'your user ocid',
tenancy_ocid => 'your tenancy ocid',
private_key => 'your user private key',
fingerprint => 'your fingerprint related to your user private key'
);
END;
/
作成したクレデンシャルを使って生成AIと連携するためのAIプロファイルを作成します。
BEGIN
DBMS_CLOUD_AI.CREATE_PROFILE(
'GENAI_COHERE',
'{
"provider": "oci",
"credential_name": "OCI_GENAI",
"model":"cohere.command-plus-latest",
"oci_apiformat":"COHERE",
"region": " ap-osaka-1",
"object_list": [
{"owner": "SNOW", "name": "ORDERS2_V"}
]
}'
);
END;
/
ADBからSnowflakeに自然言語で問い合わせしてみる
設定は以上で完了しましたので、実際に使ってみます。
-- SELECT AI実行
SELECT DBMS_CLOUD_AI.GENERATE(prompt => 'ORDERS2_V表のデータ件数はいくつですか?',
profile_name => 'GENAI_COHERE',
action => 'runsql')
FROM dual;
SELECT DBMS_CLOUD_AI.GENERATE(prompt => 'ORDERS2表でorder statusが3-Shippedのデータ件数はいくつですか?',
profile_name => 'GENAI_COHERE',
action => 'runsql')
FROM dual;
念のため自然言語から変換されたSQLを確認してみます。
-- action を showsql に変更して生成されたSQLを表示
SELECT DBMS_CLOUD_AI.GENERATE(prompt => 'ORDERS2表でorder statusが3-Shippedのデータ件数はいくつですか?',
profile_name => 'GENAI_COHERE',
action => 'showsql')
FROM dual;
SQLを見る限り意図した内容になっていました。
以上、ADBから異種DBへのDBLinkを経由し、Snowflakeに自然言語で問い合わせるADB Sidecarの検証でした。
散在した多様なDB製品内のデータをすぐに活用したいケースで特に役立てて頂けるかと思います。
ご参考情報
ちなみにSnowflakeコンソールからファイルアップロードしてデータロードする作業において、アップロードと同時に新規テーブルを作成させると以下のような定義のテーブルが作られます。
create or replace TABLE CYBERSYN.PUBLIC.ORDERS (
ID NUMBER(38,0),
ORDER_KEY NUMBER(38,0),
ORDER_STATUS VARCHAR(16777216)
);
文字列のカラムにおいて VARCHAR
を 16777216
byteで定義していますが、これがADBからアクセスする際に問題となります。
具体的には当該カラムをADBからDBLink経由でSELECTすると以下エラーが発生しますので、ご注意ください。
ORA-00997: LONGデータ型は使用できません。
https://docs.oracle.com/error-help/db/ora-00997/
00997. 00000 - "illegal use of LONG datatype"
*Cause: A value of datatype LONG was used in a function or in a
DISTINCT, WHERE, CONNECT BY, GROUP BY, or ORDER BY clause. A
LONG value can only be used in a SELECT clause.
*Action: Remove the LONG value from the function or clause.
Error at Line: 1 Column: -75