Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Oracle APEX利用事例紹介

Oracle APEX利用事例紹介

APEX UG Meetup 2019#1 - #事例を共有しよう!
1. 文書管理
2. セミナー管理
3. FAQ管理

Yuji Nakakoshi

February 12, 2019
Tweet

More Decks by Yuji Nakakoshi

Other Decks in Technology

Transcript

  1. Copyright © 2018, Oracle and/or its affiliates. All rights reserved.

    | Oracle APEX利用事例紹介 日本オラクル株式会社 2019年2月12日 APEX UG Meetup 2019#1 - #事例を共有しよう! 1
  2. Copyright © 2018, Oracle and/or its affiliates. All rights reserved.

    | Safe Harbor Statement The following is intended to outline our general product direction. It is intended for information purposes only, and may not be incorporated into any contract. It is not a commitment to deliver any material, code, or functionality, and should not be relied upon in making purchasing decisions. The development, release, and timing of any features or functionality described for Oracle’s products remains at the sole discretion of Oracle. 2
  3. Copyright © 2018, Oracle and/or its affiliates. All rights reserved.

    | 紹介事例 文書管理 セミナー管理 FAQ管理 1 2 3 3
  4. Copyright © 2018, Oracle and/or its affiliates. All rights reserved.

    | はじめに • 文書管理 – https://github.com/ujnak/apexapps/blob/master/exports/tcweb-doc.sql • セミナー管理 – https://github.com/ujnak/apexapps/blob/master/exports/tcweb-sem.sql • FAQ管理 – https://github.com/ujnak/apexapps/blob/master/exports/tcweb-faq.sql 4 免責事項 以上のアプリケーションはAPEX UserGroup@東京のメンバーへの情報提供 のみを目的としています。以下、参照のこと h0ps://github.com/ujnak/apexapps/blob/master/LICENSE
  5. Copyright © 2018, Oracle and/or its affiliates. All rights reserved.

    | 紹介事例 文書管理 セミナー管理 FAQ管理 1 2 3 5
  6. Copyright © 2018, Oracle and/or its affiliates. All rights reserved.

    | こんなアプリケーション • ファイルのアップロードと 保存 • URLの登録 • 登録したファイル、URLを 一覧表示 • Oracle Textによる全文検 索、タグ、作成者による 検索 • ファイルのダウンロード • 上記のように、機能はす ごく単純 6
  7. Copyright © 2018, Oracle and/or its affiliates. All rights reserved.

    | 作成した経緯 • 元々は20年くらい前に作成された、Javaで作られた資料共有サイトが存 在した。 • パッチを当てるため、アプリケーション・サーバーをアップグレードしようと したが、アップグレードできず。 • アプリが古くて、アプリの改修ができず。 • セキュリティ・パッチの当てられない環境は運用できないと、IT部門よりお 達し。 • 仕方がないので、アプリ部分だけAPEXで作り直した – データ移行は大変なのでDBのスキーマとデータは、そのまま使った。 7
  8. Copyright © 2018, Oracle and/or its affiliates. All rights reserved.

    | 8 ファセットっぽい検索 単語はOracle Textによって索引づ けされた、文書のタイトル、概要、 文書自身を対象として検索。 ✖のクリックで条件から除く #で始まる条件は、タグとし て認識し、概要に記載され ているハッシュタグを検索 @で始まる条件は、文書の 所有者を検索。 所有者だけOR条件 単語、ハッシュタグ(#で始まる)、所有者(@で始まる)を入 力して、検索条件はつねに追加 資料に編集権限があれば、鉛筆マーク(更新画面へのリンク)が表示 検索にヒットした文書 が持つハッシュタグ のみ表示 クリックで絞り込み 以前は動的PL/SQLで 生成していたが、レ ポート・テンプレート の自作に変更
  9. Copyright © 2018, Oracle and/or its affiliates. All rights reserved.

    | 9 文書の登録・編集 編集権限を他のユー ザーに割り当てます。 バージョンを変えると、 以前のバージョンをアー カイブします。 アーカイブされた資料を削除する機能はまだ実装してないです。。。
  10. Copyright © 2018, Oracle and/or its affiliates. All rights reserved.

    | 10 公開区分 ユーザーTAROの表示 ユーザーHANAKOの表示 公開区分がプライベートの場合 所有者であるか、編集権限のあ るユーザーにのみリストされる
  11. Copyright © 2018, Oracle and/or its affiliates. All rights reserved.

    | 11 文書検索のSQLは頑張ってます /* Document - 検索結果一覧 */ with tags_wv as ( select c001 as tag from apex_collections where collection_name = 'SEARCH_HASHTAGS' ), owners_wv as ( select c001 as owner from apex_collections where collection_name = 'SEARCH_OWNERS' ), doc_tags_wv as ( select link_num from tcw_hashtags where hashtag in (select tag from tags_wv) group by link_num having count(*) >= (select count(*) from tags_wv) ), doc_words_wv as ( select l.link_num from tcw_documents l left outer join tcw_doc_data d on l.link_num = d.link_num where contains(d.link_object, :AI_CONTAINS) > 0 or contains(l.obj_name, :AI_CONTAINS) > 0 or contains(l.abstract, :AI_CONTAINS) > 0 group by l.link_num ), doc_own_wv as ( select d.link_num from tcw_documents d left outer join tcw_doc_acls a on d.link_num = a.link_num where d.opl_code > 0 and d.in_consulting <= nvl(:IN_CONSULTING, 0) and (d.opl_code < 6 or d.upd_username = :APP_USER or a.user_name = :APP_USER) group by d.link_num ), doc_acls_wv as ( select d.link_num from tcw_documents d left outer join tcw_doc_acls a on d.link_num = a.link_num where d.opl_code > 0 and d.in_consulting <= nvl(:IN_CONSULTING, 0) and ( ( d.opl_code < 6 and ( d.upd_username in (select owner from owners_wv) or a.user_name in (select owner from owners_wv) ) ) or ( d.opl_code = 6 and ( ( d.upd_username in (select owner from owners_wv) and d.upd_username = :APP_USER ) or ( a.user_name in (select owner from owners_wv) and a.user_name = :APP_USER ) ) ) ) group by d.link_num ) select case when l.upd_username = :APP_USER or l.link_num in (select link_num from tcw_doc_acls where user_name = :APP_USER) then '<a href="' || apex_page.get_url(p_page => 2, p_clear_cache => 2, p_items => 'P2_LINK_NUM', p_values => l.link_num) || '"><span class="t-Icon fa&#x20;fa-pencil"></a>' else '' end rowop, l.link_num as link_num, case when l.opl_code = 1 then '<div class="tcw-confsquare orange" title="公開資料"/>' when l.opl_code = 2 then '<div class="tcw-confsquare blue" title="Company Confidential"/>' when l.opl_code = 3 then '<div class="tcw-confsquare green" title="Internal Use Only"/>' when l.opl_code = 4 then '<div class="tcw-confsquare red" title="Strictly Confidential"/>' when l.opl_code = 5 then '<div class="tcw-confsquare black" title="Consulting Only"/>' when l.opl_code = 6 then '<div class="tcw-confsquare black" title="Private"/>' else to_char(l.opl_code) end opl_code_text, case when d.link_object is not null then '<a href="' || 'f?p=' || :APP_ID || ':DOWNLOAD:' || :APP_SESSION || '::NO::DOWNLOAD_LINK_NUM:' || l.link_num || '" title="' || d.file_name || '">' || l.obj_name || '</a><p class="tcw- Abstract">'||htf.escape_sc(substr(l.abstract,1,80))||'...</p>' when l.link_url is not null then '<a href="' || l.link_url || '" title="' || l.link_url || '">' || l.obj_name || '</a><p class="tcw- Abstract">'||htf.escape_sc(substr(l.abstract,1,80))||'...</p>' else l.obj_name end title, case when u.last_name is null then '<a href="' || apex_page.get_url(p_page => 5, p_request => 5, p_items => 'P0_KEYWORD', p_values=> '@' || l.upd_username) ||'">'|| tcw_util.get_name_part(l.upd_username) ||'</a>' else '<a href="' || apex_page.get_url(p_page => 5, p_request => 5, p_items => 'P0_KEYWORD', p_values=> '@' || l.upd_username) ||'">'|| u.last_name || ' ' || u.first_name||'</a>' end owner, l.upd_date updated, t.content_type_alias type, k.link_names related_url, l.upd_username r_last_updated_by, l.opl_code r_classification, l.obj_name r_title from tcw_documents l left outer join (tcw_doc_data d left outer join tcw_content_types t on d.content_type = t.content_type) on l.link_num = d.link_num left outer join tcw_user_names u on l.upd_username = u.user_name left outer join tcw_doc_links_v k on l.link_num = k.link_num where l.opl_code > 0 and l.in_consulting <= nvl(:IN_CONSULTING, 0) and ( ( case when (select count(*) from apex_collections where collection_name in ('SEARCH_WORDS','SEARCH_HASHTAGS','SEARCH_OWNERS')) = 0 and nvl(tcw_util.get_preference('CARE_NEWARRAIVAL'),'Y') = 'Y' then ( select x.link_num from tcw_documents x where x.upd_date > add_months(sysdate, -1) and x.announce_flag = 1 and x.link_num = l.link_num ) else l.link_num end ) = l.link_num and ( case when :AI_CONTAINS is not null then (select v.link_num from doc_words_wv v where v.link_num = l.link_num) else l.link_num end ) = l.link_num and ( case when (select count(*) from tags_wv) > 0 then (select v.link_num from doc_tags_wv v where v.link_num = l.link_num) else l.link_num end ) = l.link_num and ( case when (select count(*) from owners_wv) > 0 then (select v.link_num from doc_acls_wv v where v.link_num = l.link_num) else (select v.link_num from doc_own_wv v where v.link_num = l.link_num) end ) = l.link_num ) 以前はPL/SQLにて動的にSQLを生成していたが書き換えた。
  12. Copyright © 2018, Oracle and/or its affiliates. All rights reserved.

    | 12 ファイル・ダウンロード ファイルのダウンロードのための直リンクは、通常のページを指定している。 Deep Linking許可、パラメーターのチェックサム保護をしない。 http://localhost:8080/ords/xepdb1/f?p=DOCUMENT:DOWNLOAD:12464312439659::NO::DOWNLOAD_LINK_NUM:10 declare l_opl_code tcw_documents.opl_code%type; l_u_email tcw_documents.reg_username%type; begin -- if opl_code is strictly confidential (4), restrict user who can download the doc. begin select opl_code, reg_username into l_opl_code, l_u_email from tcw_documents where link_num = :DOWNLOAD_LINK_NUM; if (l_opl_code = 4 and l_u_email <> :APP_USER) then apex_util.redirect_url(p_url => apex_page.get_url(p_page => '10')); -- else if (l_opl_code = 5 and nvl(:IN_CONSULTING, 0) <> 1) then -- apex_util.redirect_url(p_url => apex_page.get_url(p_page => '10')); end if; exception when no_data_found then null; -- no restriction needed. end; -- log the request and redirect to actual download page if user is valid. tcw_util.log_download_history(:DOWNLOAD_LINK_NUM, :APP_USER, systimestamp); apex_util.redirect_url( p_url => apex_util.get_blob_file_src('P6_LINK_OBJECT', :DOWNLOAD_LINK_NUM) ); end; 直リンクとなるページに、レンダリング前のプ ロセスとして指定している。 最終的にapex_u^l.get_blob_file_src()で得ら れるダウンロード・リンクへ apex_u^l.redirect_url()でリダイレクトしてい る。 現時点では積極的にダウンロードを公開区分 で制限していはいない。 後で困るので、アプリケーション・エイリアス、 ページ・エイリアスは積極的に使用する。
  13. Copyright © 2018, Oracle and/or its affiliates. All rights reserved.

    | 13 更新通知の設定 対象資料の更新や、このユー ザーによる資料の新規登録や 更新をメールにて通知 (ユーザー名がメール・アドレス を前提としているので、そうで 無い場合は動かないはず) 直リンクをクリップボードにコピー
  14. Copyright © 2018, Oracle and/or its affiliates. All rights reserved.

    | 14 ダウンロード履歴の保存 procedure log_download_history ( p_link_num in number, p_username in varchar2, p_timestamp in timestamp with local time zone) as l_c number; l_doc_owner tcw_documents.upd_username%type; PRAGMA AUTONOMOUS_TRANSACTION; begin -- avoid duplicate download within 1 hour. select count(*) into l_c from tcw_download_history where link_num = p_link_num and username = p_username and date_download between systimestamp - interval '1' hour and systimestamp; if l_c = 0 then -- do not log if referer is a document owner select upd_username into l_doc_owner from tcw_documents where link_num = p_link_num; if l_doc_owner <> p_username then insert into tcw_download_history(link_num, username, date_download, last_updated_by) values(p_link_num, p_username, p_timestamp, l_doc_owner); end if; end if; commit; end; 開始済みのトランザクションとは独立したト ランザクションとして、コミットされます。
  15. Copyright © 2018, Oracle and/or its affiliates. All rights reserved.

    | 15 アプリケーションの入れ替え 外部に公開するリンクには、アプリケーションID(数値)は使わ ず、 アプリケーションの別名(エイリアス)を使う。 アプリケーションの入れ替え時には、エイリアスを入れ替える。 入れ替え元のアプリケーションのステータスを「使用不可(リダ イレクト)」に設定し、アクセスがあれば、新しいアプリケーション にリダイレクトさせる。 アプリケーション定義の編集
  16. Copyright © 2018, Oracle and/or its affiliates. All rights reserved.

    | 紹介事例 文書管理 セミナー管理 FAQ管理 1 2 3 16
  17. Copyright © 2018, Oracle and/or its affiliates. All rights reserved.

    | こんなアプリケーション • 開催するセミナーの登録 • 登録されたセミナーの一 覧表示 • セミナーへの参加登録 • 参加の承認および拒否 • 参加者へのメール通知 • 実績確認 • 上記なので、機能はすご く単純 17
  18. Copyright © 2018, Oracle and/or its affiliates. All rights reserved.

    | 作成した経緯 • 元々は20年くらい前に作成された、PL/SQL(mod_plsql)で作成されたセミ ナー管理アプリが運用されていた。 • 所管部門がそのアプリの運用を停止し、別のアプリに移行した。 • 機能が同じでなく、利用者としては移行が難しかった。 • 最低限、データベースのチーム(私の所属)で開催するセミナーについて、 開催通知と参加申請のできるアプリを作った。 • 他のチームも使うようになった。 18
  19. Copyright © 2018, Oracle and/or its affiliates. All rights reserved.

    | セミナーの一覧表示 19 クラシック・レポートの レポート・テンプレートだけは カスタムで作成。 標準のカレンダー 標準の対話レポート
  20. Copyright © 2018, Oracle and/or its affiliates. All rights reserved.

    | セミナーの登録と編集 20 セミナー編集 自分が登録したセミナーをリスト そのセミナーの出席者一覧 対話グリッドのマスター・ディ テールの実装を利用 セミナー登録 セミナーを開催するにあ たり、必要な情報を入力 する 普通のフォーム セミナーをキャンセル(キャンセルと削除は扱いが異なりま す)したり、各種通知の機能があります。 セミナーの属性として、以下を選べる 募集中/募集停止 公開/非公開 会場開催のあり/なし オンライン開催のあり/なし 自動承認/手動承認
  21. Copyright © 2018, Oracle and/or its affiliates. All rights reserved.

    | 21 セミナーの参加 オンラインで出席を選ぶと、次から選べるボタンが変わります。 部屋で出席を選んだ場合。 参加を検討している方でも、出席者の一覧を確認できます。
  22. Copyright © 2018, Oracle and/or its affiliates. All rights reserved.

    | 22 その他 APEX_MAIL_QUEUEの内容を表示 HTMLDB_MAIL_LOGの内容を表示 通知メールの送信を確認する。 セミナー実績のレポート。
  23. Copyright © 2018, Oracle and/or its affiliates. All rights reserved.

    | 紹介事例 文書管理 セミナー管理 FAQ管理 1 2 3 23
  24. Copyright © 2018, Oracle and/or its affiliates. All rights reserved.

    | こんなアプリケーション • 質問と回答の登録 • Oracle Textによる全文 検索、タグによる検索 • 上記なので、機能はす ごく単純 24
  25. Copyright © 2018, Oracle and/or its affiliates. All rights reserved.

    | 作成した経緯 • データベースのチームでは、もともとAPEXベースのFAQサイトが運用され ていた。 • 全社的なFAQシステムが導入され、そちらに移行することになった。 • 移行しきれない情報が残った。 • 残った情報を入れる簡単なアプリを試しに作ってみた。 25
  26. Copyright © 2018, Oracle and/or its affiliates. All rights reserved.

    | FAQの一覧と登録 26 検索の仕組みは文書管理から流用 FAQの表示 FAQの登録・編集 Plain Text, Rich Text(HTML)、 Markdownを選択できるよう にした点は頑張りました。
  27. Copyright © 2018, Oracle and/or its affiliates. All rights reserved.

    | 各種形式の登録 27 プレイン・テキストでの記載 リッチ・テキストでの記載 マークダウンでの記載
  28. Copyright © 2018, Oracle and/or its affiliates. All rights reserved.

    | まとめ • 全部のポータル・アプリ – https://github.com/ujnak/apexapps/blob/ master/exports/tcweb-launcher.sql 28 免責事項 以上のアプリケーションはAPEX UserGroup@東京のメンバーへ の情報提供のみを目的としています。以下、参照のこと https://github.com/ujnak/apexapps/blob/master/LICENSE
  29. Copyright © 2018, Oracle and/or its affiliates. All rights reserved.

    | Safe Harbor Statement The preceding is intended to outline our general product direcQon. It is intended for informaQon purposes only, and may not be incorporated into any contract. It is not a commitment to deliver any material, code, or funcQonality, and should not be relied upon in making purchasing decisions. The development, release, and Qming of any features or funcQonality described for Oracle’s products remains at the sole discreQon of Oracle. 29