e-learning、オラクル研修、LMS(学習管理システム)のiStudy

e-learning、オラクル研修、LMS(学習管理システム)のiStudy

第109回「WEBアプリ作成(7)改行を含む文字データの表示」

2014.11.06

こんにちは。インストラクターの蓑島です。

前回は、データ登録のWEBアプリを完成させました。
もちろん登録されたデータはWEBアプリから表示できる必要があります。
特定の1レコードを表示するアプリは、バックナンバー第104回「WEBアプリ作成(2)(キーを指定して1レコードを表示)」などで解説済みです。

今回皆さんと一緒に考えたいのは、「データには、改行された文字データが含まれている」という問題です。
すなわち備考欄(EMP2表のNOTE列 CLOB型)です。
改行された文字データを「バックナンバー第104回」のやり方のように、HTP.P(~)で単純に表示すると、改行されずに表示されてしまいますよね。これはHTMLの仕様です。そこでなんらかのタグを使って、改行されている文字データを改行して表示してみましょう。
例えば、改行も含めて書いた通りに表示したいときは、プレタグ<PRE>~</PRE>を使うのが便利です。
ということで、今回はプレタグ<PRE>をご紹介します。

まず「バックナンバー第104回」の方法は、前述のとおり、単純に取得したデータをHTP.P(~)を使って表示していました。
例えば、取得した文字データが変数 V1 に格納されているときに、これを表示するため、以下のように記述したとします。

    HTP.P(V1);

しかしこの方法だと、変数V1に格納されている文字データが改行されている文字データであっても、改行されずに表示されます。
そこで、以下のように文字列連結して、プレタグ(<PRE>~</PRE>)で囲みます。

    HTP.P('<PRE>' || V1 || '</PRE>'); 

これで、改行された文字データであっても、きちんと改行されて表示されます。簡単ですね。

では早速、やってみましょう。
以下のプロシージャは「バックナンバー第104回」で作成した1レコードを表示するプロシージャをEMP2表用に改造したものです。
ただし比較のため、まだプレタグ(<PRE>)は使っていません。
名前をEMP2_SHOWとしてあります。

SQL> SHOW USER
ユーザーは"SCOTT"です。

SQL> L
  1  create or replace
  2  PROCEDURE EMP2_SHOW ( P_EMPNO IN VARCHAR2)
  3  IS
  4     V_EMPNO  NUMBER(4);
  5     REC   EMP2%ROWTYPE;
  6     V_ERRM VARCHAR2(500);
  7     -- 部門名を取得するファンクション
  8     FUNCTION  FNC_DNAME (P_DEPT_NO IN NUMBER) RETURN  VARCHAR2
  9     IS
 10       V_DEPT_NAME  DEPT.DNAME%TYPE;
 11     BEGIN
 12        SELECT DNAME INTO V_DEPT_NAME  FROM  DEPT WHERE DEPTNO = P_DEPT_NO;
 13        RETURN  V_DEPT_NAME;
 14     EXCEPTION
 15        WHEN NO_DATA_FOUND THEN
 16            RETURN NULL;
 17     END FNC_DNAME;
 18  BEGIN
 19     -- パラメータの社員番号(VARCHR2)をNUMBER型に変換する
 20     V_EMPNO := TO_NUMBER(P_EMPNO);
 21     SELECT * INTO REC FROM EMP2 WHERE EMPNO = V_EMPNO;
 22     -- 以下は1レコード取得後の処理
 23     HTP.P('<HTML>');
 24     HTP.P('<HEAD><TITLE>社員レコード表示</TITLE></HEAD>');
 25     HTP.P('<BODY>');
 26     HTP.P('<H1>社員明細 </H1>');
 27     HTP.P('<TABLE BORDER="1">');
 28     HTP.P('<TR><TD BGCOLOR="SILVER">社員番号</TD>'
 29          || '<TD>' || TO_CHAR(REC.EMPNO) ||'</TD></TR>');
 30     HTP.P('<TR><TD BGCOLOR="SILVER">社員名</TD>'
 31          || '<TD>' || REC.ENAME ||'</TD></TR>');
 32     HTP.P('<TR><TD BGCOLOR="SILVER">入社日</TD>'
 33          || '<TD>' || TO_CHAR(REC.HIREDATE,'YY/MM/DD') ||'</TD></TR>');
 34     HTP.P('<TR><TD BGCOLOR="SILVER">部門</TD>'
 35          || '<TD>' || FNC_DNAME(REC.DEPTNO) ||'</TD></TR>');
 36     HTP.P('<TR><TD BGCOLOR="SILVER">備考</TD>'
 37          || '<TD>' || REC.NOTE ||'</TD></TR>');
 38     HTP.P('</TABLE>');
 39     HTP.P('</BODY>');
 40     HTP.P('</HTML>');
 41  EXCEPTION
 42     WHEN  NO_DATA_FOUND THEN
 43           HTP.P('エラー: 社員番号 ' || P_EMPNO ||' は存在しません');
 44     WHEN  OTHERS  THEN
 45           V_ERRM  := SQLERRM;
 46           HTP.P(V_ERRM);
 47* END;
SQL> /

プロシージャが作成されました。

21行目のSELECT文でわかるように、EMP2表の1レコードを取得します。そして、ここで注目していただきたいのは、36~37行目です。
改行された文字を含むNOTE列の表示処理がありますが、プレタグ(<PRE>~</PRE>)で囲っていないので改行されずに表示されてしまいます。

 37行目  || '<TD>' || REC.NOTE ||'</TD></TR>'); ← REC.NOTEをプレタグ(<PRE>~</PRE>)で囲っていない。

では、実行して確認してみましょう。
前回登録したデータは、私の環境では、社員番号 7938なので、その社員のレコードを表示します。皆さんは、データにより違う社員番号である可能性があるので、適時読み替えてください。

バックナンバー第103回「WEBアプリ作成(1) (Oracle DBとPL/SQLだけで、即、WEBアプリ)」の設定ができていれば、以下のURLで実行できます。

http://localhost:8080/dad/emp2_show?p_empno=7938

そうすると、いつものようにユーザ名とパスワードを求められますので、SCOTTユーザの名前とパスワードを指定します。

以下の表示がされるはずです。

備考欄は改行されていませんね。

これを改行できるようにしたソースコードは以下の通りです。

SQL> L
  1  create or replace
  2  PROCEDURE EMP2_SHOW ( P_EMPNO IN VARCHAR2)
  3  IS
  4     V_EMPNO  NUMBER(4);
  5     REC   EMP2%ROWTYPE;
  6     V_ERRM VARCHAR2(500);
  7     -- 部門名を取得するファンクション
  8     FUNCTION  FNC_DNAME (P_DEPT_NO IN NUMBER) RETURN  VARCHAR2
  9     IS
 10       V_DEPT_NAME  DEPT.DNAME%TYPE;
 11     BEGIN
 12        SELECT DNAME INTO V_DEPT_NAME  FROM  DEPT WHERE DEPTNO = P_DEPT_NO;
 13        RETURN  V_DEPT_NAME;
 14     EXCEPTION
 15        WHEN NO_DATA_FOUND THEN
 16            RETURN NULL;
 17     END FNC_DNAME;
 18  BEGIN
 19     -- パラメータの社員番号(VARCHR2)をNUMBER型に変換する
 20     V_EMPNO := TO_NUMBER(P_EMPNO);
 21     SELECT * INTO REC FROM EMP2 WHERE EMPNO = V_EMPNO;
 22     -- 以下は1レコード取得後の処理
 23     HTP.P('<HTML>');
 24     HTP.P('<HEAD><TITLE>社員レコード表示</TITLE></HEAD>');
 25     HTP.P('<BODY>');
 26     HTP.P('<H1>社員明細 </H1>');
 27     HTP.P('<TABLE BORDER="1">');
 28     HTP.P('<TR><TD BGCOLOR="SILVER">社員番号</TD>'
 29                  || '<TD>' || TO_CHAR(REC.EMPNO) ||'</TD></TR>');
 30     HTP.P('<TR><TD BGCOLOR="SILVER">社員名</TD>'
 31                  ||'<TD>' || REC.ENAME ||'</TD></TR>');
 32     HTP.P('<TR><TD BGCOLOR="SILVER">入社日</TD>'
 33                  || '<TD>' || TO_CHAR(REC.HIREDATE,'YY/MM/DD') ||'</TD></TR>');
 34     HTP.P('<TR><TD BGCOLOR="SILVER">部門</TD>'
 35                  || '<TD>' || FNC_DNAME(REC.DEPTNO) ||'</TD></TR>');
 36     HTP.P('<TR><TD BGCOLOR="SILVER">備考</TD>'
 37                  || '<TD><PRE>' || REC.NOTE ||'</PRE></TD></TR>');
 38     HTP.P('</TABLE>');
 39     HTP.P('</BODY>');
 40     HTP.P('</HTML>');
 41  EXCEPTION
 42     WHEN  NO_DATA_FOUND THEN
 43           HTP.P('エラー: 社員番号 ' || P_EMPNO ||' は存在しません');
 44     WHEN  OTHERS  THEN
 45           V_ERRM  := SQLERRM;
 46           HTP.P(V_ERRM);
 47* END;
SQL> /

プロシージャが作成されました。

37行目を見てください。
プレタグ(<PRE>~</PRE>)を追加しただけです。

(変更前)
 || '<TD>' || REC.NOTE ||'</TD></TR>');

(変更後)
 || '<TD><PRE>' || REC.NOTE ||'</PRE></TD></TR>');

すなわち、備考の値 REC.NOTEは、HTML表のセルの中(<TD>~</TD>)にあるわけですが、セルの中にあってもなくても、とにかくプレタグ(<PRE>~</PRE>)で囲むわけです。
これで改行されて表示されます。

では、もう一度、実行してみましょう。
先ほどと同じURLです。
http://localhost:8080/dad/emp2_show?p_empno=7938

そうすると以下の結果です。

今度は改行されて表示されていますね。
このように改行された文字データを表示する場合は、プレタグ(<PRE>~</PRE>)を使えばいいわけです。

まとめますと、改行された文字列の登録と表示については・・・

登録時 <TEXTAREA  NAME="パラメータ名">~</TEXTAREA>
表示時  <PRE>~</PRE>

ということですね。

では今回はここまでにいたします。次回はデータ登録(UPDATE)がテーマです。
ご期待ください。

先頭へ戻る