[OCI]OCI FunctionsのファンクションをAutonomous DatabaseからSQLファンクションとして呼び出してみた

# はじめに
先日の機能追加で、OCI FunctionsのファンクションをAutonomous DatabaseからSQLファンクションとして呼び出すことができるようになりました。

OCI FunctionsのファンクションをSQLファンクションとして呼び出すには、[DBMS_CLOUD_FUNCTIONパッケージ](https://docs.oracle.com/en/cloud/paas/autonomous-database/serverless/adbsb/dbms-cloud-function.html#GUID-0720B3D6-D92C-4179-9A92-4B22008597E8)を使用して設定を行います。

今回は、OCI Functionsに事前定義済ファンクションとして用意されている「[Object Storage File Zip](https://docs.oracle.com/ja-jp/iaas/Content/Functions/Tasks/functions_pbf_catalog_object_storage_file_zip.htm)」を「object_storage_file_zip」という名前のファンクションとしてデプロイし、「object_storage_file_zip」ファンクションをAutonomous DatabaseからSQLファンクションとして呼び出してみました。

AWS LambdaのファンクションをAutonomous DatabaseからSQLファンクションとして呼び出す場合の記事はこちら。

https://qiita.com/500InternalServerError/items/d8c79b9bf2cc3435613e

なお、今回はadminユーザとしてAutonomous Databaseに接続して検証を行いました。

# 1.クレデンシャルの作成

DBMS_CLOUD.CREATE_CREDENTIALプロシージャで、DBMS_CLOUD_FUNCTIONパッケージで使用するクレデンシャルを作成します。
今回はテナント管理者のAPIキーを使用してクレデンシャルを作成しました。
```
SQL> BEGIN
  2      DBMS_CLOUD.CREATE_CREDENTIAL (
  3         credential_name => 'OCI_CRED',
  4         user_ocid       => 'ocid1.user.oc1..xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
  5         tenancy_ocid    => 'ocid1.tenancy.oc1..xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx,
  6         private_key     => '-----BEGIN PRIVATE KEY-----
　　　　　　　　＜略＞
 33  -----END PRIVATE KEY-----',
 34         fingerprint     => 'xx:xx:xx:xx:xx:xx:xx:xx:xx:xxxx:xx:xx:xx:xx:xx');
 35  END;
 36* /

PL/SQLプロシージャが正常に完了しました。

SQL> 
```
# 2. ファンクションのカタログの作成 
DBMS_CLOUD_FUNCTION.CREATE_CATALOGプロシージャを使用して、ファンクションのカタログを作成します。
ここでは、クレデンシャルとして1.で作成したOCI_CREDを使用して、cloud_paramsで指定したリージョンおよびコンパートメント内にあるOCI Functinsのファンクションを含むカタログOCI_DEMO_CATALOGを作成しています。
```
SQL> BEGIN
  2      DBMS_CLOUD_FUNCTION.CREATE_CATALOG (
  3          credential_name  => 'OCI_CRED', 
  4          catalog_name     => 'OCI_DEMO_CATALOG', 
  5          service_provider => 'OCI',
  6          cloud_params     => '{"region_id":"ap-tokyo-1", "compartment_id":"ocid1.compartment.oc1..xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}'
  7      );
  8  END;
  9* /

PL/SQLプロシージャが正常に完了しました。

SQL>
```

# 3. カタログの同期
DBMS_CLOUD_FUNCTION.SYNC_FUNCTIONSプロシージャを使用して、カタログOCI_DEMO_CATALOGのスコープ内にあるOCI Functionsのファンクションに対するPL/SQLラッパーを作成します。

```
SQL> BEGIN
  2   DBMS_CLOUD_FUNCTION.SYNC_FUNCTIONS (
  3          catalog_name => 'OCI_DEMO_CATALOG'
  4   );
  5  END;
  6* /

PL/SQLプロシージャが正常に完了しました。

SQL> 
```

# 4. カタログの内容の確認
DBMS_CLOUD_FUNCTION.LIST_FUNCTIONSプロシージャを使用して、カタログOCI_DEMO_CATALOGの内容を確認します。

```
SQL> VAR function_list CLOB;
SQL> 
SQL> BEGIN
  2      DBMS_CLOUD_FUNCTION.LIST_FUNCTIONS (
  3         credential_name  => 'OCI_CRED', 
  4         catalog_name     => 'OCI_DEMO_CATALOG',
  5         function_list    => :function_list);
  6  END;
  7* /

PL/SQLプロシージャが正常に完了しました。

SQL> 
SQL> SELECT JSON_QUERY(:function_list, '$' RETURNING VARCHAR2(32676) pretty) AS search_results FROM dual;

SEARCH_RESULTS                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    
_________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________ 
[
  {
    "functionName" : "object_storage_file_zip",
    "functionId" : "ocid1.fnfunc.oc1.ap-tokyo-1.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "invokeEndpoint" : "https://xxxxxxxxxxx.ap-tokyo-1.functions.oci.oraclecloud.com"
  }
]    

SQL> 
```
ファンクションobject_storage_file_zipがカタログOCI_DEMO_CATALOGに登録されていることが確認できました。

describeコマンドでファンクションobject_storage_file_zipの情報を確認してみます。
```
SQL> desc object_storage_file_zip

FUNCTION object_storage_file_zip RETURNS CLOB

引数名     タイプ   In/Out    デフォルトかどうか    
_________ _______ _________ ____________ 
PARAMS    CLOB    IN        unknown      
SQL>
```

# 5. Autonomous DatabaseからOCI Functionsのファンクションを実行

ファンクションobject_storage_file_zipは、指定したオブジェクト・ストレージ・バケット内のオブジェクトをZIPで固めて、指定したバケットに保存するという動作を行います。

ここでは東京リージョンにあるバケットSourceBucket内にあるファイルをZIPで圧縮して、バケットTargetBucket内に保存してみます。

まず、バケットSourceBucketの内容を確認します。
```
SQL> SELECT object_name, created
  2  FROM
  3  DBMS_CLOUD.LIST_OBJECTS(
  4    'OCI_CRED', 
  5    'https://objectstorage.ap-tokyo-1.oraclecloud.com/n/namespace/b/SourceBucket/o'
  6* );

OBJECT_NAME      CREATED                                
________________ ______________________________________ 
testdata1.txt    02-NOV-22 02.47.12.833000000 AM GMT    
testdata2.txt    02-NOV-22 02.47.13.203000000 AM GMT    
testdata3.txt    02-NOV-22 02.47.13.411000000 AM GMT    
testdata4.txt    02-NOV-22 02.47.13.626000000 AM GMT    
testdata5.txt    02-NOV-22 02.47.13.906000000 AM GMT    

SQL> 
```
バケットSourceBucketには5つのファイルが格納されています。

バケットTargetBucketの内容を確認します。
```
SQL> SELECT object_name, created
  2  FROM
  3  DBMS_CLOUD.LIST_OBJECTS(
  4    'OCI_CRED', 
  5    'https://objectstorage.ap-tokyo-1.oraclecloud.com/n/namespace/b/TargetBucket/o'
  6* );

行が選択されていません
SQL> 
```
バケットTargetBucketにはファイルが格納されていません。

以下のSQLでOCI Functionsのファンクションobject_storage_file_zipを実行します。
指定するパラメータの詳細は[こちら](https://docs.oracle.com/ja-jp/iaas/Content/Functions/Tasks/functions_pbf_catalog_object_storage_file_zip.htm#pbf-object-storage-file-zip-policies-plus__invoking-object-zip)に記載があります。
```
SQL> SELECT object_storage_file_zip(
  2    '{
  3        "COMPARTMENT_ID": "compartment_id":"ocid1.compartment.oc1..xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  4        "REGION": "ap-tokyo-1",
  5        "SOURCE_BUCKET": "SourceBucket",
  6        "SOURCE_FILES": "/",
  7        "TARGET_BUCKET": "TargetBucket/ZippedByFunction.zip",
  8        "ALLOW_OVERWRITE": "true"
  9    }' 
 10  ) as response
 11* FROM dual;

RESPONSE                                                                                                                                                                                                                                                                                                                         
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________ 
{"STATUS":200,"RESPONSE_BODY":"{\"startTime\":\"2023-10-06T04:53:02.523303052Z\",\"endTime\":\"2023-10-06T04:53:18.242651321Z\",\"runTime\":\"PT15.719303349S\",\"code\":200,\"status\":\"Success\",\"data\":{\"additionalInformation\":{\"Message\":\"Zip File: ZippedByFunction.zip uploaded to Bucket: TargetBucket\"}}}"}    

SQL> 
```
ファンクションobject_storage_file_zipの実行が完了したら、バケットTargetBucketの内容を確認します。
```
SQL> SELECT object_name, created
  2  FROM
  3  DBMS_CLOUD.LIST_OBJECTS(
  4    'OCI_CRED', 
  5    'https://objectstorage.ap-tokyo-1.oraclecloud.com/n/namespace/b/TargetBucket/o'
  6* );

OBJECT_NAME             CREATED                                
_______________________ ______________________________________ 
ZippedByFunction.zip    06-OCT-23 04.14.44.228000000 AM GMT    

SQL> 
```
バケットTargetBucket内に、OCI Functionsのファンクションobject_storage_file_zipによって作成されたZIPファイルZippedByFunction.zipが作成されていることが確認できました。

以上で、OCI FunctionsのファンクションをAutonomous DatabaseからSQLファンクションとして呼び出せることが確認できました。

# 参考情報
・[Invoke User Defined Functions](https://docs.oracle.com/en/cloud/paas/autonomous-database/serverless/adbsb/user-defined-functions-autonomous.html#GUID-8E002919-CA8A-418D-B66D-0F5B8B719D3A)
・[DBMS_CLOUD_FUNCTION Package](https://docs.oracle.com/en/cloud/paas/autonomous-database/serverless/adbsb/dbms-cloud-function.html#GUID-0720B3D6-D92C-4179-9A92-4B22008597E8)
・[Object Storage File Zipファンクション](https://docs.oracle.com/ja-jp/iaas/Content/Functions/Tasks/functions_pbf_catalog_object_storage_file_zip.htm)