Apexで複数ファイルを一括アップロード

<h1>はじめに</h1>
Apexにのデフォルト機能としてファイルアップロードはありますが、1ファイルずつ登録する仕様となっているため複数ファイルを登録したい場合は少々手間がかかります。そこで、どうにか複数ファイルを一括登録する方法はないのかなぁと探していたところ、こちらのブログ(https://blogs.ontoorsolutions.com/post/upload_multiple_file_in_oracle_apex/ )を見つけました。こちらの記事では、画像ファイルを表示させていますがその部分をDBにInsertするように書き換えることで実装できます。

<h1>テーブルを準備</h1>
まずは、ファイルを登録するテーブルを作成します。
```PL/SQL
CREATE TABLE SAMPLE_FILES(
	FILE_ID NUMBER GENERATED ALWAYS AS IDENTITY,
	FILE_TYPE NUMBER ,
	FILE_NOTE VARCHAR2(256) ,
	FILE_CONTENTS BLOB ,
	FILE_MIMETYPE VARCHAR2(300) ,
	FILE_NAME VARCHAR2(1600) ,
	FILE_CHARSET VARCHAR2(300) ,
	);
```

<h1>表示するページを作成</h1>
ファイルを登録するテーブルを表示させるページを作成します。対話グリッドで先ほど作成したSAMPLE_FILESを指定。
<br>
<img width="400" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/681023/57380ddc-b606-bf2a-39de-eb6815eaf8c8.png">
<img width="400" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/681023/f80f157f-52ad-8afd-c44d-6b5cf3ed5ff4.png">
<img width="400" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/681023/cc11dce0-90c7-4e69-5bc6-7131c4d57eb2.png">
<img width="400" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/681023/d0496cec-5bcf-38c7-59a2-01cd7d21b4b2.png">
<img width="400" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/681023/2dbd9931-9cc7-6b58-8298-cc4bee855aa8.png"><br>
そしてこのまま作成して、ページを開こうとすると問題なく表示できますが、この後ファイルを登録した後にページを表示させようとすると以下のようなエラーになります。
<img width="400" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/681023/5d6116b1-00db-e289-3e92-4d5808dd4e53.png">


なので、対話グリッドの列から、FILE_CONTENTすなわちBLOBの列を削除してください。<br>
<img width="200" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/681023/ce1c6c3f-e8b0-9a45-92d8-4a3a88e850dd.png">

<h1>アップロードするためのページを作成</h1>
一旦、FILE_UPLOADという空白のページを作成しました。
ここにファイルアップロードのアイテムと、登録用ボタン、INSERTプロセスを作成していきます。<br>
まずはファイルアップロードのアイテム。複数ファイルの許可をONにするのを忘れずに。<br>
<img width="200" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/681023/f7664a5d-3f9c-6c7a-84c6-054e0cc881b3.png">


次に登録用ボタン。動作は、ページの送信にします。
<img width="200" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/681023/e37de72f-ee31-3ba0-e8a5-a98c4d80977a.png">
<img width="200" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/681023/916499fc-1736-28a0-2686-9bd9b15cc6b0.png">

そして、INSERTプロセスを作成します。
<img width="200" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/681023/12d9433e-3418-d4bf-6c33-c4116aa46190.png">
PL/SQLの中身はこんな感じ。
```PL/SQL
declare
    l_file_names apex_t_varchar2;
    l_file       apex_application_temp_files%rowtype;
begin

  APEX_COLLECTION.CREATE_OR_TRUNCATE_COLLECTION(
	p_collection_name=>'FILES'
  );

    l_file_names := apex_string.split (
                        p_str => :P3_FILE,
                        p_sep => ':' );
    for i in 1 .. l_file_names.count loop
        select *
          into l_file
          from apex_application_temp_files
         where name = l_file_names(i) and APPLICATION_ID=:APP_ID;     

         INSERT INTO　SAMPLE_FILES(FILE_CONTENTS, FILE_MIMETYPE, FILE_NAME)
         VALUES(l_file.BLOB_CONTENT, l_file.MIME_TYPE, l_file.FILENAME);

    end loop;
end;
```
プロセスの後に、元のページに戻るブランチを作成します。
<img width="200" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/681023/94cad6d2-2e7a-90a8-67a2-1971031b8e82.png">
これで、アップロードするページの作業は以上です。


<h1>アップロードするためのページに遷移するボタンを作成</h1>
アップロードするためのページに遷移するためのボタンを作成します。<br>
<img width="200" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/681023/a602e1ed-640c-2d00-1781-d8f823f13815.png"><br>
<img width="200" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/681023/a2adce78-98fb-f2d1-2fe3-fbd7ff0e3d40.png">

<h1>実際の動作がこちら</h1>
まずはUploadをクリック<br>
<img width="400" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/681023/2d02b72e-b121-a7a1-849a-eac180231b09.png"><br>
複数ファイルを選択してUpdateをクリック。<br>
<img width="400" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/681023/9af57ab7-a3ed-d869-2f33-fee672a72460.png">

するとこうなる！
<img width="400" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/681023/81c0f0e2-fdb1-02b9-5b29-d8de7cf9ba33.png">

このままだとほんとにDBに登録できてるの??っていう感じなので、ダウンロードも作成していきます。
と思ったが面倒なので、対話モードレポートにしちゃいましょう！
ダウンロードするときに使用するダウンロードという仮想列を作成しておきます。
<img width="200" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/681023/998147d8-9f52-1564-49da-685432be8d27.png">
<img width="200" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/681023/5ce6ad5b-ba30-36c5-4de5-91e09b4b8a5d.png">

DOWNLOADの列タイプを<b>BLOBのダウンロード</b>にします。(これが対話グリッドにはないのです)
<img width="200" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/681023/610cc7c5-833b-768d-af72-66a9e96803e8.png">

<img width="200" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/681023/2c39de56-f9f3-aec2-4764-daadcfcf2c7a.png">

そしたら、ダウンロードできるようになりました！
と言いたいところなのですが、エラーが発生しているのでしばしお待ちを。