Migaro. 技術Tips

                       

ミガロ. 製品の技術情報
IBMiの活用に役立つ情報を掲載!


Valenceグリッドで「旧式の」日付を操作する

(※このトピックスは、Valence開発元(米CNX社)のブログ記事を翻訳・再編集したものとなります。原文記事は、コチラとなります。)

もし、あなたの会社のERPシステムのデータベースが1980年代や1990年代初頭に誕生し、それ以来あまり「進化」していないのであれば、おそらく日付の値が数値フィールドに格納されているファイルが多数あることでしょう。日付が年/月/日のフィールドに分かれて解析されているか、YYYYMMDDやCYYMMDDといった単一のフィールドに格納されているかどうかにかかわらず、日付の演算、フィルタリング、ソートといった単純なことを行う際に越えなければならないハードルについては、すでによくご存知のことでしょう。

Valence はもちろん物理的なファイル構造をアップグレードしたり変更することはできませんが、Valence App Builder といくつかの簡単な SQL トリックによって、グリッド・ウィジェットにデータを表示する際に、日付以外のフィールドを扱うプロセスを少し簡単にする方法があります。このヒントでは、パフォーマンスを犠牲にすることなく、グリッドとグリッドフィルタをAS/400の初期の遺物として動作させる最善の方法に焦点を当てます。

YYYYMMDD形式の日付が数字で書かれたファイルがあり、それをグリッドの形でユーザーに見せたいとします。データソースを作成して、1つまたは複数のファイルから必要なカラムを取得し、グリッド・ウィジェットにリスト表示するのは簡単です。次に、グリッド・ウィジェットのカラムの書式(フォーマッティング)を設定して、YYYYMMDDの数値カラムをYYYY-MM-DDやMM-DD-YYYYなどの従来の日付表現構造に変換できます。

Date Renderer from YYYYMMDD

しかし、ユーザーがその日付カラムに基づいてリストをフィルタリングできるようにしたい場合はどうすればいいのでしょうか? グリッドの書式設定は、バックエンドから SQL 結果を取得した後にブラウザで適用されることに留意してください。したがって、数値の日付カラムをフィルターフィールドとして指定した場合、カレンダーのような日付選択オプションを提供する通常の日付カラムと同じようには扱われません。むしろ、フィルターフィールドは標準的な8桁の数値フィールドとなり、ユーザーはその下にあるYYYYMMDD形式で日付を入力することが期待されます。このため、グリッドの日付がMM-DD-YYYYのようなユーザー・フォーマットで表示されると、ユーザーは少し混乱するかもしれません(下図参照)。

Date filter confusion

これを回避する一つの方法は、データソースに計算カラムを作成し、数値の日付をISOの日付に変換することです。これは、TIMESTAMP_FORMAT関数や独自のカスタム関数を使って行うことができます(”SHIPDT “はYYYYMMDD形式で保存された数値フィールドとします)。

SELECT ordno, prdno, qty, um,
DATE(TIMESTAMP_FORMAT(char(shipdt),'YYYYMMDD')) as shipdt_iso
FROM order_dtl

計算された列であるSHIPDT_ISOは数値フィールドではなく真の日付フィールドであるため、グリッドのフィルタとしてその列を選択すると自動的に日付ピッカー・ボタンが表示され、フィールドは[ポータル管理] > [設定] > [日付フォーマット]で指定したのと同じ日付構造に従って表示されるようになります。

Standard date filter

これは、基礎となるファイルのレコード数が比較的少ない場合には、許容できる方法です。しかし、何百万ものレコードを含むファイルでは、このアプローチに関連するパフォーマンス・ペナルティが発生する可能性があります。これは、ウィジェットのデータソースにWHERE句を追加して、特定のカラム値に基づいて結果を制限する場合、App BuilderはSELECT句でそのカラムに指定された同じロジックを適用しなければならないからです。言い換えると、計算されたカラムでフィルタリングする場合、WHERE句は同様にその計算を含みます。一般的に、WHERE句にカラム値に対する関数や計算を含めると、SQLエンジンはファイル内のすべてのレコードを評価して、どれがフィルタ条件に当てはまるかを判断する必要がありますが、最適化するように最善を尽くします。

このパフォーマンスの問題を解決する方法として、私たちは、すべてのデータソースで1つの目的を果たす基本的な2列のワークファイルを作成することを提案しています。これは、数値の日付列を、各列に別々の論理またはインデックスを使用して、真のISO日付列に変換するものです。例えば、2000年から2050年までのすべての日付を保持するために、一度だけファイルを初期化する簡単なプログラムを作成すれば、日付フィルタリングを使用するすべてのデータソースに結果のワークファイルを含めることができます。

例として、数値日付からISO日付への変換グローバルワークのファイルが以下のようなものであるとします。

Date conversion work file

このワークファイルを使用するには、データソースのselect節でshipdtをISOの日付に変換するのではなく(先に説明したとおり)、代わりに日付の数値で変換ファイルに結合します。その結果、次のようなデータソースができあがります。

SELECT ordno, prdno, qty, um, isodate as shipdt_iso
FROM order_dtl
INNER JOIN date_conv on numdate=shipdt

これを導入すると、注文詳細ファイルからSHIPDT数値カラムではなく、作業ファイルからISODATE日付カラムをグリッドに取り込むことになります。ISODATE (この場合 SHIPDT_ISO のエイリアス) は真の日付カラムなので、グリッドフィルターは標準の日付ピッカー機能を含み、カラムの書式設定で指定された同じ日付形式を引き継ぎます。

このINNER JOINワークファイルアプローチを使用して、数値の日付をISOの日付に変換した場合のパフォーマンスの向上は、非常に顕著なものです。200万件近いレコードを含む顧客注文ファイルに対して行った粗いテストでは、SELECT句とWHERE句で計算された日付列を使用した場合と、このJOINアプローチで特定の日付範囲をフィルタリングした場合では、システムが結果セットを得るのにほぼ3倍速くなったことがわかりました。

この日付フィルタリングのパフォーマンスシナリオに対処するために、グリッドウィジェットでフィルタオーバーライドプログラムを使用する別のオプションがあります。この方法は「ハイブリッド」ソリューションとして機能します。つまり、フィルタで計算された日付カラムを使用し、WHERE句で元のカラムに同等のYYYYMMDD値を適用してパフォーマンスのペナルティを回避することができるのです。このフィルターオーバーライドの概念については、次回のブログで取り上げる予定です。