今回はDelphi/400でソートしたデータの並び順について、制御方法をご紹介いたします。
はじめに
通常、SQLで取得するデータをソートする場合、
ORDER BY句で並び替えるフィールドを指定します。
ORDER BY句を使用するとそのフィールドでソートされますが、
意図しない順序で並んでしまう場合もあります。
例えば文字フィールドでアルファベットと数字のデータがあった場合、
アルファベット文字が上位になるケースと、数字が上位になるケースがあります。
これは並び替えが行われる文字セットによっての違いです。
IBM i 上でORDER BYした場合はEBCDIC文字セットでソートされるため、
アルファベット文字が数字よりも上位になります。
具体的には、SQLの取得結果は通常以下の3種類のいずれかのソート順となります。
- EBCDIC順(A~Z<0~9 の順に表示、IBM i 標準)
- ASCII順(0~9<A~Z の順に表示、Windows標準)
- 到着順(キーの値を問わず、IBM i 側の物理レコード順で表示)
ORDER BYを行わずにSELECTした場合、
元ファイルのキー順でソートされる場合と、到着順でソートされる場合があります。
(ORDER BYを行っていない場合のソート順は、IBM i 側で保証されていません。
基本的には、IBM i でSTRSQLから同じSELECTのSQLを発行した場合と同じ並び順になります。)
BDE/dbExpress接続
IBM i 上でORDER BYした場合はEBCDIC文字セットでソートされるため、
アルファベット文字が数字よりも上位になります。(EBCDIC順)
Delphi/400のプログラムでTClientDataSetなどでデータを表示する場合はASCII文字セットで
ソートされるため、数字がアルファベット文字よりも上位になります。(ASCII順)
Delphi/400のプログラムでTClientDataSetを使用時、通常はASCII順になりますが、
IBM i 上のEBCDIC文字セットでソートを行いたい場合には、
TDataSetProviderのOptionsプロパティでpoRetainServerOrderという設定をTrueにすることで、
サーバー側のEBCDIC文字セット順を有効にできます。
FireDAC接続
FireDAC接続においては、TDataSetProviderで先述のpoRetainServerOrderをTrueに設定しても
ソート順を変更することができません。
EBCDIC順でデータの取得を行う場合、FireDAC接続ではTFDQueryを使用し、
TFDQueryのSQL文内でORDER BY句を使ってフィールドの並び順を指定します。
降順の指定時は対象フィールドの後ろに「DESC」を付与します。
<例 FireDACのSQLでEBCDIC順 >
SELECT * FROM FILE1 ORDER BY FIELD1, FIELD2 DESC, FIELD3
FireDAC接続においてASCII順でデータの取得を行う場合、
クライアント側でIndexを設定するのが最もシンプルです。
対象のTFDQueryやTFDTableのIndexFieldNamesプロパティを設定します。
TClientDataSetとは異なり、「(フィールドID):D」と指定すると降順にもできます。
<例 ASCII順のIndexFieldNames設定 >
FIELD1;FIELD2:D;FIELD3
到着順でのソート方法
接続方式を問わず、意図的に到着順でレコードを表示させたい場合は、
それぞれの接続方式のQueryを使用し、SQL文内で
RRN(IBM i 側で保持している相対レコード番号)に対してORDER BY句を指定します。
<例 到着順のSQL >
SELECT * FROM FILE1 ORDER BY RRN(FILE1)
新規開発で到着順を選択する機会はあまりないかもしれませんが、
バージョンアップで接続方式を変更する場合に、新旧でソート順を統一するのに役立ちます。
(BDE/DBX:ミガロ.情報マガジン「MIGARO News!!」Vol.178 2015年9月号より)
(FireDAC:ミガロ.テクニカルレポート Vol.11 技術論文より)
(RRN:ミガロ.情報マガジン「MIGARO News!!」Vol.221 2019年7月号より)