スクリプトを用いた主キーの拡張

最終更新日: 2021年12月15日
R8 | R9

レポートモデル内の「ステータス」項目によって、次のルールが適用されるものとします。

新規顧客
N1404001 (1桁目:N, 2〜5桁目:年月, 6〜8桁目:001...999連番)
既存顧客
E1404001 (1桁目:W, 2〜5桁目:年月, 6〜8桁目:001...999連番)

このように、区分毎に連番を用意します。

図1に新規顧客のレポート登録を、図2に既存顧客のレポート登録の例を示します。いずれも連番は001となっており、独立して管理されます。

図1 新規顧客のレポート,主キーがN1404001となっている
図2 既存顧客のレポート,主キーがE1404001となっている

定義方法

「レポート」モデルの全体構成を図3に示します。

図3 レポートモデル

主キー項目「ID」の、主キーに関する詳細は設定しません。(図4)これをスクリプトとして実現します。[後述]

図4 主キーの詳細設定を行わない

「ID」項目を入力時は隠し項目・読込専用として扱います。これによって主キーですが入力なし(自動設定)を実現できます。

図6 隠しと読込専用の設定

「ステータス」モデルの初期値を図6に示します。"新規" はコード1を、"既存" はコード2をそれぞれ割り当てます。

図7 ステータスモデルの初期値

順序を定義する

区分毎の連番を用意するため、Wagbyが用意した順序テーブル "seq" に独自の順序 "report_seq1" と "report_seq2" を登録します。それぞれ開始番号を "1" とします。

独自の DDL を発行するために、$(DEVHOME)/customize/webapp/WEB-INF/export/conf/initdb_ex.xml を用意します。(図7)(*1)

exportフォルダならびに export/conf フォルダは手動で作成してください。
図8 initdb_ex.xmlを新規作成する

次の内容とします。

図9 initdb_ex.xmlの内容
<?xml version="1.0" encoding="UTF-8"?>
  <sql group="data"
        acceptcommand="sql sql-create-after" denycommand="all"
        tablename="seq">
INSERT INTO &quot;seq&quot; VALUES('report_seq1',1);
INSERT INTO &quot;seq&quot; VALUES('report_seq2',1);
  </sql>

ビルド後は以下に配置されます。(*1)
wagbyapp/webapps/wagby/WEB-INF/export/conf/initdb_ex.xml

1. R7.12.6/R8.0.4 より前のバージョンの Wagby で Java 9 以上の環境を利用する場合、initdb_ex.xml を $(DEVHOME)/customize/tomcat/bin に配置してください。ビルド後は wagbyapp/bin にコピーされます。(R7.12.6/R8.0.4 以降の Wagby では、この手順は不要です。)

ここでは順序テーブル "seq" を使いましたが、お使いのデータベースが順序の仕組みをもっている場合、CREATE SEQUENCE で順序を作成するとよいでしょう。(Oracle, PostgreSQL, SQL Server 2012 は順序を提供しています。)

ワンポイント

このようにinitdb_ex.xmlは、sql要素中に独自のDDLを記述することができます。Wagbyによるデータベース作成時に、順序やビューの作成など、独自のDDLを発行できます。[関連ページ:インポートとエクスポート機能活用ガイド(R8) > 設定ファイル > 拡張ファイル initdb_ex.xml]

注意

テーブル名を囲むダブルクォートの有無などは、ご利用になるデータベースによって異なります。

スクリプトを実装する

「画面 > スクリプト」を開きます。新規登録時のスクリプトコードを作成します。
これは新規登録処理の最後に呼び出されますので、主キーの値をセットするのに都合のよいポイントです。

図10 主キー生成のためのコード
var CommonService = Java.type("jp.jasminesoft.jfc.app.CommonService");
var seq;
var prefix;
if (report.status == 1) {    
    /* 順序の使い分け */
    /* CommonServiceはWagbyが提供するクラス */
    /* p はWagbyが提供するオブジェクト */
    seq = CommonService.getSeq(p, "report_seq1");
    prefix = "N";
} else if (report.status == 2) {
    seq = CommonService.getSeq(p, "report_seq2");
    prefix = "E";
}
/* デバッグ用 print("seq="+seq+",prefix="+prefix);*/
var pkey = prefix;
/* new Date() は JavaScript のオブジェクトを利用 */
var today = new Date();
/* String() は JavaScript のオブジェクトを利用 */
var year = String(today.getFullYear());
var month = String(today.getMonth()+1);
/* ExcelFunctionはWagbyが提供するクラス */
/* ゼロ詰めにし、年部分の右2桁を取得する */
pkey = pkey + ExcelFunction.RIGHT(ExcelFunction.PADDING("0",2,year),2);
/* ゼロ詰めにし、月部分の右2桁を取得する */
pkey = pkey + ExcelFunction.RIGHT(ExcelFunction.PADDING("0",2,month),2);
/* ゼロ詰めにし、順序部分の右3桁を取得する */
pkey = pkey + ExcelFunction.RIGHT(ExcelFunction.PADDING("0",3,String(seq)),3);
/* reportモデルのreportid項目が文字列型の主キー */
report.reportid = pkey;
  • RIGHT 関数は、文字列の右からN桁までを取り出します。
  • PADDING 関数は、文字列に指定文字を詰めて、切り出します。
CREATE SEQUENCE で順序を作成した場合、CommonService.getSeq ではなく CommonService.getSequence を使ってください。