PL/SQL de File Upload / Download #2 Tweet

さて、環境が整ったのでプロシージャを作成する。
(今回はマニュアルに記載されているサンプルのようにそれぞれ独立したプロシージャとしたが、これらを纏めてパッケージ化しても問題ない。 私が仕事で依頼されたものならパッケージとして実装するでしょうね。)
OTN-J の Code Tipsでも公開されました。(2007/6/16更新)
http://otn.oracle.co.jp/otn_pl/otn_tool/code_detail?n_code_id=2235
http://otn.oracle.co.jp/otn_pl/otn_tool/code_detail?n_code_id=2236
4.ファイルアップロード/ダウンロードプロシージャの例
注)style属性のtext-shadowを利用していますが、MacOSXのSafari以外のブラウザではドロップシャドウ効果はありません。
URLの例)- hostnameが discus 、 portが 7780 である場合、以下のようなURLでアクセスする。
http://discus:7780/plsql_de_fileupload/fileuploadform
(1)ファイルを最大5件同時にアップロードするフォームを表示するプロシージャ。
参考:
http://otndnld.oracle.co.jp/document/products/oracle10g/102/doc_cd/server.102/B19260-01/concept.htm#i1005985
http://otndnld.oracle.co.jp/document/products/oracle10g/102/doc_cd/server.102/B19260-01/concept.htm#i1011204
CREATE OR REPLACE PROCEDURE fileUpLoadForm
IS
numOfFiles CONSTANT PLS_INTEGER := 5;
BEGIN
htp.htmlopen;
htp.headopen;
htp.meta('CONTENT-TYpe',null,'text/html; charset=Shift_JIS');
htp.title('PL/SQL de File Upload');
htp.headclose;
htp.bodyopen;
htp.centeropen;
htp.print('<div align="center" style="width:500; height:600">');
htp.STRONG(
cattributes=> 'style="font-size:24px; color:#ff0000; '
|| 'text-shadow:1px 2px 3px #7f7f7f"',
ctext=> 'PL/SQL de ファイルアップロード'
);
htp.prn('<br><br>');
htp.formopen(
cenctype=>'multipart/form-data',
curl=>'action',cmethod=>'POST'
);
FOR i IN 1..numOfFiles LOOP
htp.prn(
'<p><span style="text-shadow:1px 2px 3px #7f7f7f">ファイルの選択:</span>'
);
htp.formfile(cname=>'file');
htp.br;
END LOOP;
htp.prn('<br><br><p>');
htp.formsubmit(cattributes=>'align=right',cvalue=>'アップロード');
htp.formclose;
htp.print('</div>');
htp.centerclose;
htp.bodyclose;
htp.htmlclose;
END;
/
(2)<FORM>要素のaction属性に指定するプロシージャの例
下記サンプルコードでは、マニュアルに記載されているサンプルの他に、同一操作でアップロードされたファイルに対してシーケンスから採番した操作番号を設定する処理を追加している。
CREATE OR REPLACE PROCEDURE action
(
file IN owa_util.vc_arr
) IS
vOpe# number(10);
BEGIN
htp.htmlopen;
htp.meta('CONTENT-TYPE',null,'text/html; charset=Shift_JIS');
htp.headopen;
htp.title('PL/SQL de File Upload (Action)');
htp.headclose;
htp.bodyopen;
htp.header(1,'アップロード・ステータス');
htp.print('以下のアップロードが終了しました。<br><br>');
htp.prn('<span style="color:#ff0000; text-shadow:1px 2px 3px #7f7f7f">');
FOR i IN file.FIRST..file.LAST LOOP
IF FILE(i) IS NOT NULL THEN
htp.print('-> ' || file(i) || '<br>');
END IF;
END LOOP;
htp.print('</span>');
-- 同一操作でアップロードしたファイルへ、同一操作番号を設定する。
SELECT upload_operation#.nextval INTO vOpe# FROM dual;
FOR i IN file.FIRST..file.LAST LOOP
UPDATE DISCUSDOCTABLE SET operation# = vOpe# WHERE name=file(i);
END LOOP;
htp.bodyclose;
htp.htmlclose;
END;
/
(3)ダウンロード可能なファイルリストを表示するプロシージャの例。
URLの例) - hostname = discus, port = 7780である場合。
http://discus:7780/plsql_de_fileupload/filelist
マニュアルに記載されているファイルダウンロードのサンプルは、同マニュアルに記載されている他のサンプルコードに比べ、少々不親切(端折り過ぎ)なサンプルコードになっている。(CGIなどのWebアプリケーションに慣れている方なら想像できなくもないのだが・・・・。)
下記サンプルコードを見れば容易に理解できると思うのだが、アップロードしたファイルをダウンロードするには、dads.confのPlsqlDocumentPathパラメータで指定したドキュメントルートのパスと、ドキュメント表のname列の値を連結したパスでダウンロードするファイル指すURLを生成できる。
CREATE OR REPLACE PROCEDURE fileList
IS
BEGIN
htp.htmlopen;
htp.headopen;
htp.meta('CONTENT-Type',null,'text/html; charset=Shift_JIS');
htp.title('PL/SQL de File upload - ダウンロード可能なファイル一覧');
htp.headclose;
htp.bodyopen;
htp.print(
'<span style="text-shadow:1px 2px 3px #7f7f7f; font-size: 22px">'
|| 'ダウンロードファイル一覧</span><br><br>'
);
FOR doc IN (SELECT name FROM discusDocTable) LOOP
htp.anchor('docs/' || utl_url.escape(doc.name, false, 'Shift_JIS'), 'docs/' || doc.name);
htp.br;
END LOOP;
htp.bodyclose;
htp.htmlclose;
END;
/
(4)ファイルのダウンロード時にmod_plsqlから呼び出されるプロシージャの例。
このプロシージャは、(3)の方法でダウンロードする場合には必須であり、dads.confのPlsqlDocumentProcedureパラメータで指定する。
このプロシージャのサンプルコードはマニュアルにも記載されているのだが少々難解ですね。
実際には、以下のように wpg_docload.download_file()プロシージャを実行するだけの処理なのだがマニュアルのサンプルコードを見ると少々混乱してしまう! 私も少々考えましたもん!!!
以下コードを見てもらうと実は非常にシンプルな操作であることに気付くと思う。 解説するまでも無いと思うが念のために解説しておくと、wpg_docload.download_file(環境変数PATH_INFOの値)を実行しているだけなのである。
CREATE OR REPLACE PROCEDURE fileDownloader
IS
vFilePath VARCHAR2(256);
BEGIN
vFilePath := SUBSTR(owa_util.get_cgi_env('PATH_INFO'), 2);
wpg_docload.download_file(vFilePath);
EXCEPTION
WHEN OTHERS THEN
htp.htmlopen;
htp.headopen;
htp.meta('Ccntent-Type',null,'text/html; charset=Shift_JIS');
htp.headclose;
htp.bodyopen;
htp.print('ダウンロードファイル:' || vFilePath);
htp.print('<strong style="color:#ff0000">' || sqlerrm() || '</strong>');
htp.bodyclose;
htp.htmlclose;
END fileDownloader;
/
以上でプロシージャの作成は終わり。 簡単ですよね!。
次回へつづく。
| 固定リンク | 0
コメント