2016年4月26日火曜日

JavaからAS/400 ~ カラムヘディング編

こんにちは、寺田です。



前回『JavaからAS/400 ~ メンバー編』に続き、今回は、物理ファイル(=テーブル)のカラムヘディング(フィールドの欄見出し)の取得方法についてお話します。

カラムヘディングとは、QUERYユーティリティーやデータ・ファイル・ユーティリティー(DFU)で使用されるフィールドのラベル(欄見出し)のことです。物理ファイルのフィールド定義(DDS)では、次のように COLHDGキーワードで定義します。
     A*
     A* ID    : SAMPLE01
     A* NAME  : 取引先マスター
     A*-------------------------------------------------------------
     A          R SAMPLE01R
     A*                                                             
     A            STATUS         1A         COLHDG(' 状態 ')
     A                                      TEXT(' 取引状態 ')
     A            CSTMNO         5A         COLHDG(' 取引先№ ')
     A            CSTMNM        30O         COLHDG(' 取引先名 ')
     A            CSTMNMK       30A         COLHDG(' 取引先カナ名 ')
     A            CSTMTEL       10A         TEXT(' 電話番号 ')
     A            CATNO          2A         COLHDG(' 業種№ ')
     A            SALES          8S 0       COLHDG(' 売上実績 ')
     A*
このカラムヘディング、AS/400ユーザにとってはお馴染みのようで、とあるお客様先で、物理ファイルのデータをExcelとしてダウンロードし、そのExcelの1行目に見出しとしてカラムヘディングを差し込むプログラムをVBとWSHで作りこんでいるのを見たことがあります。見出しはカラム名(上記のDDSではCSTMNOやCSTMNM)ではなくてカラムヘディングで表示するのが、AS/400ユーザでは常識のようです。

そこで、Java(JT400)でカラムヘディングを取得する方法を以下に紹介します。

1つ目は、JDBCの仕様の範囲だけで取得する方法です。
以下がそのサンプルです。
Connection con = null;
try {
    Class.forName("com.ibm.as400.access.AS400JDBCDriver");
    con = DriverManager.getConnection(
            "jdbc:as400://as400server;prompt=false", "USER", "PASSWD");
    DatabaseMetaData dmd = con.getMetaData();
    ResultSet rs = dmd.getColumns(null, "MYLIB", "MYFILE", "%");
    while(rs.next()) {
        System.out.println(rs.getString("COLUMN_NAME")
             + "," + rs.getString("REMARKS"));
    }
    rs.close();
} catch (Exception e) {
    e.printStackTrace();
}
finally {
    try {
        if (con != null) {
            con.close();
        }
    } catch(SQLException e) {
    }
}
DatabaseMetaDataクラスのgetColumns()メソッドによって、指定の物理ファイルのフィールド情報を取得します。結果がResultSetで返されてきますが、カラムヘディングはカラム名"REMARKS"に格納されています。

なお、上記のDDSのように、フィールドにCOLHDGキーワードだけでなくTEXTキーワード(テキスト記述)も定義されている場合、REMARKSにはTEXTキーワードで定義した情報が格納されます。REMARKSの情報がカラムヘディングなのか、テキスト記述なのかは判別できません。

2つ目は、毎度ですがJT400(JTOpen)のユーティリティクラスを使用する方法です。
try {
    AS400 as400 = new AS400("as400server", "USER", "PASSWD");
    as400.setGuiAvailable(false);
    as400.connectService(AS400.SIGNON);
    String path = "/QSYS.LIB/MYLIB.LIB/MYFILE.FILE";
    AS400FileRecordDescription file = new AS400FileRecordDescription(as400, path);
    RecordFormat[] format = file.retrieveRecordFormat();
    for (int i = 0; i < format[0].getNumberOfFields(); i++) {
        FieldDescription fd = format[0].getFieldDescription(i);
        System.out.println("NAME=" + fd.getFieldName());
        System.out.println("COLHDG=" + fd.getCOLHDG());
        System.out.println("TEXT=" + fd.getTEXT());
    }
}
catch (Exception e) {
    e.printStackTrace();
}
AS400FileRecordDescriptionクラスのretrieveRecordFormat()メソッドでレコード情報を取得。各フィールドのFieldDescriptionオブジェクトからカラムヘディングを取得します。この場合、カラムヘディング(COLHDG)とテキスト記述(TEXT)をそれぞれ取得するメソッドが用意されています。

3つ目は、AS/400のコマンドDSPFFD(ファイル・フィールド記述表示)を使用する方法です。この方法が、一番詳細なフィールド情報を取得することができます。

コマンドDSPFFD(ファイル・フィールド記述表示)は、その名のとおり、物理ファイルのフィールド情報を出力するコマンドです。出力されるフィールド情報には、カラムヘディングはもちろん、データタイプや長さ、さまざまな属性値なども含まれています。

例えば、次のようにコマンドを発行すると、
DSPFFD FILE(MYLIB/MYFILE) OUTPUT(*OUTFILE) OUTFILE(MYLIB/MYFILEFFD)
ファイルMYLIB/MYFILEのフィールド情報が、ファイルMYLIB/MYFILEFFDに出力されます。つまり、フィールド情報がDBのテーブルとして参照できるということです。フィールド情報のファイルを予め作成しておくか、以前のプログ『JavaからAS/400のコマンドを発行するには』で紹介したようにJT400でコマンドを発行し、あとは普通にJDBCで検索すればいい訳です。

実は、2つ目のAS400FileRecordDescriptionクラスを使う方法は、中身はDSPFFDコマンドを使った実装になっています。JT400は、JTOpenとしてソースが公開されています。そのソースを覗いてみると、いろいろと発見があって面白いですよ。


0 件のコメント:

コメントを投稿