2025年6月4日水曜日

BLOBとBase64エンコードしたCLOBの相互変換をPL/SQLとMLE JavaScriptで実行する

主にネットワーク上でバイナリ・データを送受信するにあたって、Base64でエンコードまたはデコードが必要な場合があります。Oracle APEXのサーバー・サイドのプロセスでの実行を想定して、PL/SQLとMLE JavaScriptで、BLOBからBase64のCLOBおよびその反対のBase64のCLOBからBLOBへ変換するコードを書いてみました。

それらのプロセスを組み込んだアプリケーションの画面です。


このAPEXアプリケーションのエクスポートを以下に置いています。
https://github.com/ujnak/apexapps/blob/master/exports/blob-handling.zip

機能はすべてホーム・ページに実装しています。

タイプファイルのアップロードであるページ・アイテムP1_FILEを作成しています。このページ・アイテムのストレージタイプ表APEX_APPLICATION_TEMP_FILESを選択することで、ボタンSUBMITをクリックしたときに実行されるプロセス内で、アップロードされたファイルをAPEX_APPLICATION_TEMP_FILESの列BLOB_CONTENTより、BLOBとして取り出せます。


ボタンSUBMITをクリックしたときに、以下の4つのプロセスを実行します(最初のプロセスInitializeはコレクションの初期化を行い、BLOBの変換処理は行いません)。
  • BLOB2BASE64_PLSQL - PL/SQLでBLOBをBase64エンコードしたCLOBへ変換します。結果をAPEXコレクションに保存します。
  • BLOB2BASE64_JS - JavaScriptでBLOBをBase64エンコードしたCLOBへ変換します。結果をAPEXコレクションに保存します。
  • BASE642BLOB_PLSQL - JavaScriptで変換したBase64のCLOBを、PL/SQLでBLOBへ変換します。結果をAPEXコレクションに保存します。
  • BASE642BLOB_JS - PL/SQLで変換したBase64のCLOBを、JavaScriptでBLOBへ変換します。結果をAPEXコレクションに保存します。
変換結果はすべてAPEXコレクションに保存されます。変換結果を確認するために、以下のSELECT文をソースとしたクラシック・レポートを作成しています。
select
    seq_id,
    c001,
    substr(clob001,1,60) clob001,
    dbms_lob.getlength(blob001) blob001
from apex_collections
where collection_name = :P1_COLLECTION_NAME
CLOBについては先頭60バイトが一致していれば、JavaScriptとPL/SQLの双方の変換で同じ、BLOBについては全体の長さが一致していればJavaScriptとPL/SQLの双方の変換で同じだろうと見做しています。より厳密さを求めるのであれば、DBMS_CRYPTO.HASHの利用も考慮する必要があります。パッケージDBMS_CRYPTOはデフォルトでは実行権限がなく、管理者によるGRANT文の実行が必要なためレポートに含めていません。


PL/SQLによるBLOBからBase64エンコードされたCLOBへの変換は、以下のコードで行なっています。Oracle APEXが提供しているAPEX_WEB_SERVICE.BLOB2CLOBBASE64を呼び出しています。


JavaScriptによるBLOBからBase64エンコードされたCLOBへの変換は、以下のコードで行なっています。Oracleが提供しているモジュールmle-encode-base64に含まれるファンクションencodeを呼び出しています。


PL/SQLによるBase64エンコードされたCLOBからBLOBへの変換は、以下のコードで行なっています。Oracle APEXが提供しているAPEX_WEB_SERVICE.CLOBBASE642BLOBを呼び出しています。


JavaScriptによるBase64エンコードされたCLOBからBLOBへの変換は、以下のコードで行なっています。Oracleが提供しているモジュールmle-encode-base64に含まれるファンクションdecodeを呼び出しています。

今回の記事は以上になります。

Oracle APEXのアプリケーション作成の参考になれば幸いです。